2012-01-17 79 views
8

TLDR;如何在编译时不知道表名时使用Entity Framework从表中读取数据?使用实体框架从动态创建的表中查询数据

有一个外部系统处理大量信息,然后为每个批次运行创建一个新表,并在该表中存储一些数据。这些新表的列布局是事先知道的,所以我从现有数据库生成了一个ADO.NET实体数据模型(edmx文件),其中有一个具有完全相同列布局的表。

该数据库中的原始表格被称为ResultTableTemplate,因此表示该表格的实体类别也被称为ResultTableTemplate

我想弄清楚如何使用我的ADO.NET实体数据模型从这些动态创建的表中读取数据,然后返回IEnumerable<ResultTableTemplate>。什么是迄今为止我所做的是这样的:

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(); 
    } 
} 

当我运行查询,我得到了以下消息System.Data.EntitySqlException

“ResultTable419828”无法在当前范围或 解决上下文。确保所有引用的变量都在范围内,需要加载 模式,并且该名称空间正确引用 。近成员访问表示,1号线,列225

ResultTable419828是我试图tableName + " AS ResultTableTemplate",但它并没有帮助的tableName

值。

我有没有前进的方向,还是必须在没有Entity Framework的帮助下做到这一点?

编辑:我现在是我写的查询文本不向下传递到底层的SQL Server实例的所有方法,但得到由实体框架返回一个ObjectQuery<ResultTableTemplate>实例解释明白,所以中查找ResultTable419828 Context的自动生成的DbSet实例。

不过,有没有办法让我做到我需要做的事情?

编辑:谢谢Ladislav Mrnka。现在,我这样做:

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

我认为这是创建一个EntityQuery,而不是数据库查询。因此,FROM是DbSet而不是数据库表。 – cadrell0 2012-01-17 15:11:40

+0

'CreateQuery ()'返回一个'ObjectQuery ' - 我现在看到你的是正确的。查询不是针对数据库表,而是针对DbSet。你认为有什么方法可以做我需要做的吗? – 2012-01-17 15:14:28

+0

我们使用DbConnection和SqlQuery 从数据库中获取标量值。我没有编写DAL的那部分内容,所以我不完全确定它的工作原理,但是您可以从那里开始。 – cadrell0 2012-01-17 15:18:16

回答

11

这不是直接可能的。当您将实体映射到ResultTableTemplate时,您可以硬编码该实体的表格名称。实体只能一次(每个型号),所以在运行时每个EF查询该实体始终会导致查询ResultTableTemplate表映射。

改变的行为改变在运行时映射文件(SSDL)这是相当丑陋的黑客攻击,因为它需要你改变XML文件,并重新加载它的唯一途径。每次更改文件时,都必须手动构建MetadataWorkspace。建筑物MetadataWorkspace是EF中性能最高的操作之一。在正常运行中,每个应用程序运行仅创建一次MetadataWorkspace

有一个简单的解决方法。你知道表名,你知道表结构 - 它是固定的。因此,使用直接的SQL和使用EF的结果物化到您的映射实体类:

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

的缺点是,你不能在这种方法中使用Linq,但你的要求不是非常适合于EF。

0

试试这个; :)

string tableName = "MyTableTest"; 

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

你能证明你如何查询表格吗? – Talon 2017-01-20 10:07:01