动态获取DbSet

Joh*_*eon 5 c# asp.net entity-framework

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

我尝试过使用这段代码:

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

dbset.AddRange(dates.[name]);
efContext.SaveChanges();
Run Code Online (Sandbox Code Playgroud)

但我收到此错误:

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

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

Iva*_*oev 3

问题是通用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);
Run Code Online (Sandbox Code Playgroud)

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

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

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