首页 > 解决方案 > 动态获取一个 DbSet

问题描述

我想得到一个DbSet我存储在变量中的类名。

我试过这段代码:

string name = "ParosLineas";
var dbset = (System.Data.Entity.DbSet)efContext.GetType().GetProperty(name).GetValue(efContext);

dbset.AddRange(dates.[name]);
efContext.SaveChanges();

但我收到此错误:

System.InvalidCastException:'无法将'System.Data.Entity.DbSet1 [Report.Models.ParosLinea]'类型的对象转换为'System.Data.Entity.DbSet'

这是我的 ParosLine 声明: 在此处输入图像描述

标签: c#asp.netentity-framework

解决方案


问题是通用DbSet<TEntity>类不继承(因此不能转换为)非通用DbSet

我看到两个选项。

如果您知道实体类的命名空间名称,则可以使用它Type.GetType来获取对应的Type名称,然后可以使用该名称来调用返回非通用对象的非通用DbContext.Set方法DbSet,例如

string nameSpace = "MyEntities";
string name = "ParosLineas";
var type = Type.GetType($"{namespace}.{name}");
var dbSet = efContext.Set(type);

另一种方法是使用反射来获取DbSet<T>属性,但将结果转换为IQueryable. 然后你可以使用IQueryable.ElementType来调用Set上面的非泛型方法:

string name = "ParosLineas";
var type = ((IQueryable)efContext.GetType().GetProperty(name).GetValue(efContext))
    .ElementType;
var dbSet = db.Set(type);

第一种方法是优选的。首先,因为它使用较少的调用,其次,因为在上下文中不需要DbSet<T>属性并且不假设DbSet<T>属性名称与实体类名称相同。


推荐阅读