2012-01-17 23 views
8

TLDR; ¿Cómo leo los datos de una tabla usando Entity Framework, cuando el nombre de la tabla no se conoce en tiempo de compilación?Consultar datos utilizando Entity Framework desde la tabla creada dinámicamente

Hay un sistema externo que procesa una gran cantidad de información, y luego crea una nueva tabla para cada ejecución por lotes, y almacena algunos datos en esa tabla. El diseño de columna de estas nuevas tablas se conoce de antemano, así que he generado un Modelo de Datos de Entidad ADO.NET (archivo edmx) desde una base de datos existente, donde hay una tabla con el mismo diseño de columnas.

La tabla original en esa base de datos se llama ResultTableTemplate, por lo que la clase de entidad que representa esa tabla también se llama ResultTableTemplate.

Estoy tratando de averiguar cómo usar mi Modelo de Datos de Entidad ADO.NET para leer desde esas tablas creadas dinámicamente, y obtener IEnumerable<ResultTableTemplate>. Lo que he hecho hasta ahora es la siguiente:

public IEnumerable<ResultTableTemplate> GetResultsFromTable(string tableName) { 
    using (var context = new WorkdataEntities()) { 
     var table = context.CreateQuery<ResultTableTemplate>("SELECT " + 
      "ALL_THOSE_COLUMN_NAMES... " + 
      "FROM " + tableName; 

     var query = from item in table select item; 

     return query.ToList(); 
    } 
} 

Cuando ejecuto la consulta, aparece un System.Data.EntitySqlException con el siguiente mensaje:

'ResultTable419828' no se pudo resolver en el ámbito actual o contexto. Asegúrese de que todas las variables referenciadas estén dentro del alcance, que los esquemas requeridos estén cargados, y que los espacios de nombres estén referenciados correctamente. Cerca de la expresión elemento de acceso, línea 1, columna 225.

ResultTable419828 es el valor de tableName

He tratado tableName + " AS ResultTableTemplate" pero no ayudó.

¿Hay alguna manera de avanzar, o tendré que hacer esto sin la ayuda de Entity Framework?

EDIT: me doy cuenta ahora que el texto de la consulta que estoy escribiendo no se pasa todo el camino a la instancia subyacente de SQL Server, pero se interpreta Marco de la entidad que devuelve una instancia ObjectQuery<ResultTableTemplate>, por lo que busca ResultTable419828 entre las instancias DbSet autogeneradas del Contexto.

Aún así, ¿hay alguna manera para mí de lograr lo que tengo que hacer?

EDITAR: Gracias Ladislav Mrnka. Ahora, hago esto:

public IEnumerable<ResultTableTemplate> GetResultsFromTable(string tableName) { 
    using (var context = new WorkdataEntities()) { 
     var query = context.ExecuteStoreQuery<ResultTableTemplate>("SELECT " + 
      "ALL_THOSE_COLUMN_NAMES... " + 
      "FROM " + tableName; 

     return query.ToList(); 
    } 
} 
+1

Creo que está creando una EntityQuery, no una consulta de base de datos. Por lo tanto, el FROM es un DbSet, no una tabla de base de datos. – cadrell0

+0

'CreateQuery ()' devuelve un 'ObjectQuery ' - y ahora veo que estás en lo correcto. La consulta no está en contra de una tabla de base de datos, sino de un DbSet. ¿Crees que hay una manera de hacer lo que tengo que hacer aquí? –

+0

Usamos un DbConnection con SqlQuery para obtener un valor escalar de la base de datos. No escribí esa parte de nuestro DAL, así que no estoy del todo seguro de cómo funciona, pero es posible que pueda comenzar allí. – cadrell0

Respuesta

11

No es directamente posible. Cuando asigna la entidad al ResultTableTemplate, codifica el nombre de la tabla para esta entidad. Las entidades se pueden asignar solo una vez (por modelo), por lo que en el tiempo de ejecución cada consulta EF para esta entidad siempre da como resultado una consulta a la tabla ResultTableTemplate.

La única forma de cambiar el comportamiento es modificar el archivo de asignación (SSDL) en el tiempo de ejecución, lo cual es bastante feo, ya que requiere cambiar el archivo XML y volver a cargarlo. Tendrá que crear MetadataWorkspace manualmente cada vez que cambie el archivo. El edificio MetadataWorkspace es una de las operaciones que más rendimiento consume en EF. En la ejecución normal, MetadataWorkspace se crea solo una vez por ejecución de la aplicación.

Hay una solución simple. Ya conoce el nombre de la tabla y conoce la estructura de la tabla: está arreglado. Así que utilice SQL directa y el uso de EF para materializar el resultado en su clase de entidad asignada:

var table = context.ExecuteStoreQuery<ResultTableTemplate>("SELECT ... FROM " + tableName); 

La desventaja es que no se puede utilizar LINQ en este enfoque, pero su requerimiento no es muy adecuado para EF.

0

Pruebe esto; :)

string tableName = "MyTableTest"; 

// Fetch the table records dynamically 
var tableData = ctx.GetType() 
       .GetProperty(tableName) 
       .GetValue(ctx, null); 
+1

¿Puede demostrar cómo consultaría la tabla? – Talon

Cuestiones relacionadas