使用Entity Framework从动态创建的表中查询数据

And*_*lad 8 c# sql entity-framework

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

当我运行查询时,我收到System.Data.EntitySqlException以下消息:

无法在当前范围或上下文中解析"ResultTable419828".确保所有引用的变量都在范围内,加载了所需的模式,并正确引用了名称空间.近成员访问表达式,第1行,第225列.

ResultTable419828 是的价值 tableName

我试过tableName + " AS ResultTableTemplate"但它没有帮助.

有没有前进的方法,或者我必须在没有实体框架的帮助下做到这一点?

编辑:我现在意识到我写的查询文本并没有一直传递到底层SQL Server实例,而是由实体框架解释,它返回一个ObjectQuery<ResultTableTemplate>实例,因此它ResultTable419828在自动生成DbSet的Context实例中查找.

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

编辑:谢谢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();
    }
}
Run Code Online (Sandbox Code Playgroud)

Lad*_*nka 10

这不是直接可能的.将实体映射到ResultTableTemplate您时,硬编码此实体的表名称.实体只能映射一次(每个模型),因此在运行时,此实体的每个EF查询始终会导致查询到ResultTableTemplate表.

改变的唯一方法是行为是在运行时修改映射文件(SSDL),这是非常难看的黑客,因为它要求您更改XML文件并重新加载它.MetadataWorkspace每次更改文件时都必须手动构建.建筑MetadataWorkspace是EF中性能最高的操作之一.在正常运行MetadataWorkspace中,每个应用程序运行仅创建一次.

有简单的解决方法.你知道表名,你知道表结构 - 它是固定的.因此,使用直接SQL并使用EF将结果具体化到映射的实体类中:

var table = context.ExecuteStoreQuery<ResultTableTemplate>("SELECT ... FROM " + tableName);
Run Code Online (Sandbox Code Playgroud)

缺点是您不能在这种方法中使用Linq,但您的要求不太适合EF.