简体   繁体   中英

Dynamically get a DbSet

I want to get a DbSet with the class name that I have stored in a variable.

I have tried with this code:

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

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

but I get this error:

System.InvalidCastException: 'Unable to cast object of type 'System.Data.Entity.DbSet1[Report.Models.ParosLinea]' to type 'System.Data.Entity.DbSet'

this is my ParosLine declaration: 在此处输入图片说明

The problem is that the generic DbSet<TEntity> class does not inherit (hence cannot be cast to) the non generic DbSet .

I see two options.

If you know the namespace name of the entity class, you can use Type.GetType to get the corresponding Type which in turn can be used to call the non generic DbContext.Set method which returns a non generic DbSet object, eg

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

Another way is to use reflection to get the DbSet<T> property as you are doung, but cast the result to IQueryable . Then you can use the IQueryable.ElementType to call the non generic Set method as above:

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

The first method is preferable. First, because it uses less calls, and second, because does not require DbSet<T> property in the context and does not assume that DbSet<T> property name is the same as the entity class name.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM