Entity Framework linq 中的动态表名

Posted

技术标签:

【中文标题】Entity Framework linq 中的动态表名【英文标题】:Dynamic table names in Entity Framework linq 【发布时间】:2015-06-24 17:21:21 【问题描述】:

我正在使用 Entity Framework 6 和 ASP.Net MVC 5。当使用数据库上下文对象时,有没有办法使用变量作为表名,而无需手动编写查询?

例如:

var tableName = "NameOfTable";

result = context.tableName.Find(...);

我知道特定代码不起作用,因为 tableName 没有在上下文中定义,但是有没有办法达到预期的效果?

这个网站上有一些类似的问题,但他们从来没有真正解决过问题,而且是针对早期版本的实体框架,所以我希望现在有答案。

【问题讨论】:

我不知道这个问题的答案,但是为您的实体创建部分类并支持表名属性可以解决您的问题吗? 您为什么要这样做?对于这种情况,我想不出一个有效的用例。或许您可以告诉我们您最终想要达到的目标是什么? 我正在尝试优化我的代码。我有几行类似的代码,唯一的区别是表的名称。我希望能够将这一行放入一个函数中并将表的名称作为参数传递。 所以你在谈论泛型而不是动态表名。比如你可以context.Set<Model>().Find(...) 【参考方案1】:

这是一个简单的解决方案,它使用开关将特定的Type 关联到一个表。您还可以保持使用某种Dictionary<string, Type> 对象。

var tableName = "Table1";
// Get proper return type.
Type returnType;
switch(tableName) 
    case "Table1":
        returnType = typeof(Table1EntityType);
        break;
    case "Table2":
        returnType = typeof(Table2EntityType);
        break;

var query = context.Set(returnType);
// Filter against "query" variable below...
var result = query.Where(...);

-或-

var tableName = "Table1";
Dictionary<string, Type> tableTypeDict = new Dictionary<string, Type>()

     "Table1", Table1Type ,
     "Table2", Table2Type 
; 
var query = context.Set(tableTypeDict[tableName]);
// Filter against "query" variable below...
var result = query.Where(...);

编辑:针对实体框架修改

EDIT2:根据@thepirat000 的建议使用typeof

【讨论】:

这是一个 LINQ-to-SQL 上下文。我正在使用实体框架,所以我正在使用 dbContext。我不知道 ExecuteQuery 的等效函数是什么。 你应该这样做returnType = typeof(TablexEntityType); context.Set 是否将整个表加载到内存中?【参考方案2】:

除了上面有用的答案,我还想添加它以防它对其他人有所帮助。

如果您在 Mark 的回答中的“Where”子句中遇到此错误:

'DbSet 不包含'Where' 的定义,并且找不到可接受的扩展方法'Where' 接受'DbSet' 类型的参数。

安装 Nuget 包“System.Linq.Dynamic.Core”使我们的错误消失了。

如果您需要访问表中的 LINQ 方法列名,您可以编写如下代码:

var tableName = "MyTableName"; 
var tableClassNameSpace = "MyProject.Models.EntityModels";

using (var dbContext = new MyEntities()) 

     var tableClassName = $"tableClassNameSpace.tableName";
     var dynamicTableType = Type.GetType(tableClassName);      // Type
     var dynamicTable = sgrContext.Set(dynamicTableType);      // DbSet

     var records = dynamicTable
           .AsQueryable()
           .ToDynamicList()
           .OrderBy(d => d.MyColumnName)
           .Select(d => new  d.MyColumnName )
           .ToList();

      // do stuff

【讨论】:

以上是关于Entity Framework linq 中的动态表名的主要内容,如果未能解决你的问题,请参考以下文章

Entity Framework Core 2.1 中的 ReverseEngineeringGenerator

利用Entity Framework修改指定字段中的值

EF6 System.Data.Entity.Core.EntityKey 在 Entity Framework Core 中的等价物是啥?

Entity Framework学习-实体框架中的code-first迁移

Entity Framework linq 中的动态表名

Entity Framework Core 2 中的 ConnectionString 生成器