Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 调用DbSet<;类型>;。在DbContext的子类中使用反射添加()方法_C#_Entity Framework_Dynamic_Reflection_Dbcontext - Fatal编程技术网

C# 调用DbSet<;类型>;。在DbContext的子类中使用反射添加()方法

C# 调用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>

我有一个DbContext子类,它通过实体框架与数据库对话。我正在使用MVC

我有n个与我的表相关的数据库集。我想为任何DbSet.Add(entityObject)调用Add方法,在本例中,使用反射或动态变量UserAccounts.Add(entityUserAccount)

我这样做是因为我需要在我的控制器中通过依赖注入注入DbContect

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();
        }