C# 调用DbSet<;类型>;。在DbContext的子类中使用反射添加()方法
我有一个DbContext子类,它通过实体框架与数据库对话。我正在使用MVC 我有n个与我的表相关的数据库集。我想为任何DbSet.Add(entityObject)调用Add方法,在本例中,使用反射或动态变量UserAccounts.Add(entityUserAccount) 我这样做是因为我需要在我的控制器中通过依赖注入注入DbContectC# 调用DbSet<;类型>;。在DbContext的子类中使用反射添加()方法,c#,entity-framework,dynamic,reflection,dbcontext,C#,Entity Framework,Dynamic,Reflection,Dbcontext,我有一个DbContext子类,它通过实体框架与数据库对话。我正在使用MVC 我有n个与我的表相关的数据库集。我想为任何DbSet.Add(entityObject)调用Add方法,在本例中,使用反射或动态变量UserAccounts.Add(entityUserAccount) 我这样做是因为我需要在我的控制器中通过依赖注入注入DbContect public class DataContext: DbContext { public DbSet<UserAccount>
public class DataContext: DbContext
{
public DbSet<UserAccount> UserAccounts { get; set; }
public void Insert<TypeEntity>(TypeEntity entity) where TypeEntity : BaseEntity
{
var typesToRegister = typeof(DataContext).GetProperties().
Where(p => p.PropertyType == typeof(DbSet<TypeEntity>));
//This is where the code explodes in face:-)
//Please let me know how to fix it
var dbSetItem = typesToRegister.First();
var methodAdd = dbSetItem.GetType().GetMethod("Add");
methodAdd.Invoke(this, new TypeEntity[] { entity });
}
}
//Insert<TypeEntity>(TypeEntity entity) is my service
//method to invoke the DbSet<T>.Add() method.
公共类DataContext:DbContext
{
公共数据库集用户帐户{get;set;}
公共无效插入(TypeEntity),其中TypeEntity:BaseEntity
{
var typesToRegister=typeof(DataContext).GetProperties()。
其中(p=>p.PropertyType==typeof(DbSet));
//这就是代码在脸上爆炸的地方:-)
//请让我知道如何修理它
var dbSetItem=TypeStoreRegister.First();
var methodAdd=dbSetItem.GetType().GetMethod(“添加”);
调用(这个,新的TypeEntity[]{entity});
}
}
//Insert(类型实体)是我的服务
//方法调用DbSet.Add()方法。
这是我得到的错误:对象引用未设置为对象的实例。
我认为你的方法有点不恰当 因为您已经在DbContext类中,所以我假设
这是上下文
var dbSet = this.Set<TypeEntity>();
dbSet.Add(entity);
到
typesToRegister.First()
返回一个PropertyInfo
,因此我们不能使用GetType
。。相反,我们使用PropertyType
你也需要这个变化
更新2
var dbSet = this.Set<TypeEntity>(); // an actual instance that can be passed to Invoke
methodAdd.Invoke(dbSet, new TypeEntity[] { entity });
var dbSet=this.Set();//可以传递以调用的实际实例
调用(dbSet,newtypeentity[]{entity});
dbSetItem
属于PropertyInfo
类型,因为您调用了GetProperties()
。它没有Add
方法,这就是为什么会得到null
(GetMethod
如果找不到匹配的方法,则返回null
)
您不能将此
传递到Invoke
的第一个参数中,它需要是类型为DbSet
的对象,并且您的数组应该是object[]
(您可以传递其他内容,因为它将自动上转换)
我修正了你的密码。有两个错误:
而不是
var methodAdd=dbSetItem.GetType().GetMethod(“添加”)
您应该这样写:(因为dbSetItem.GetType()将返回propertyType,而不是您期望的字段类型)
dbSetItem.GetValue(this.GetType().GetMethod(“Add”)
并更改此行(因为应该以这种方式调用Add方法:db.Items.Add(…)而不是db.Add(…)
调用(这是新的TypeEntity[]{entity>})
对此:
调用(dbSetItem.GetValue(this),新类型实体[]{entity>})
您是否忘记在代码末尾调用SaveChanges方法
public void Insert<TypeEntity>(TypeEntity entity) where TypeEntity: BaseEntity
{
var typesToRegister = typeof(DataContext).GetProperties().
Where(p => p.PropertyType == typeof(DbSet<TypeEntity>));
var dbSetItem = typesToRegister.First();
var methodAdd = dbSetItem.GetValue(this).GetType().GetMethod("Add");
methodAdd.Invoke(dbSetItem.GetValue(this), new TypeEntity[] { entity });
SaveChanges();
}
public void Insert(TypeEntity实体),其中TypeEntity:BaseEntity
{
var typesToRegister=typeof(DataContext).GetProperties()。
其中(p=>p.PropertyType==typeof(DbSet));
var dbSetItem=TypeStoreRegister.First();
var methodAdd=dbSetItem.GetValue(this.GetType().GetMethod(“Add”);
调用(dbSetItem.GetValue(this),新的TypeEntity[]{entity});
保存更改();
}
那么,代码有什么问题吗?是的,我知道,但我想使用反射。这是我正在做的一个基本例子,但对于实际问题,我需要思考。@Luther,我已经给出了我的答案。此更改不会导致空值。我已经按照您所说的编辑了代码,但在“methodAdd.Invoke(dbsetItem,new TypeEntity[]{entity};”(我还使用了object而不是TypeEntry)行中,我得到了一个错误:“mscorlib.dll中发生了类型为'System.Reflection.TargetException'的异常,但未在用户代码中处理其他信息:对象与目标类型不匹配。”@Luther我想我现在理解了这个问题。TypeStoreRegister.First()只是向您提供类型,而不是它的实例。您需要传递一个要调用的实例。我正在再次修改答案以包含此内容。我仍然收到一个错误,null ref。异常:“其他信息:对象引用未设置为对象的实例。“@Luther:没有注意到这个问题,dbSetItem
是一个PropertyInfo
,您需要调用PropertyType
。请详细说明更改的内容和原因。这样我们都可以学到一些东西。
var dbSet = this.Set<TypeEntity>(); // an actual instance that can be passed to Invoke
methodAdd.Invoke(dbSet, new TypeEntity[] { entity });
var dbSetItem = typesToRegister.First().PropertyType;
methodAdd.Invoke(dbSetItem, new object[] { entity });
public void Insert<TypeEntity>(TypeEntity entity) where TypeEntity: BaseEntity
{
var typesToRegister = typeof(DataContext).GetProperties().
Where(p => p.PropertyType == typeof(DbSet<TypeEntity>));
var dbSetItem = typesToRegister.First();
var methodAdd = dbSetItem.GetValue(this).GetType().GetMethod("Add");
methodAdd.Invoke(dbSetItem.GetValue(this), new TypeEntity[] { entity });
SaveChanges();
}