在DbContext的子类中使用反射调用DbSet <type> .Add()方法

时间:2015-07-13 23:40:46

标签: c# entity-framework dynamic reflection dbcontext

我有一个DbContext子类,它通过实体框架与数据库进行通信。我正在使用MVC C#。

我有与我的桌子相关的n个DbSets。我想使用反射或动态变量为任何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.

这是我得到的错误:对象引用未设置为对象的实例。 enter image description here

3 个答案:

答案 0 :(得分:2)

我修复了你的代码。有两个错误:

  1. 而不是
  2.   

    var methodAdd = dbSetItem.GetType()。GetMethod(“Add”);

    你应该写:(因为dbSetItem.GetType()将返回propertyType而不是你期望的字段的类型)

      

    dbSetItem.GetValue(本).GetType()GetMethod( “添加”);

    1. 并更改此行(因为应该以这种方式调用Add方法:db.Items.Add(...)而不是db.Add(...))
    2.   

      methodAdd.Invoke(this,new TypeEntity [] {entity&gt;});

      到那一个:

        

      methodAdd.Invoke(dbSetItem.GetValue(this),new TypeEntity [] {entity&gt;});

      您是否忘记在代码末尾调用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();
          }
      

答案 1 :(得分:0)

我认为你的方法有点过时了。

由于您已经在DbContext类中,我假设this是上下文。

var dbSet = this.Set<TypeEntity>();

                dbSet.Add(entity);

<强>更新

你应该改变

dbsetItem.GetType().GetMethod("Add");

dbsetItem.PropertyType.GetMethod("Add");

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

答案 2 :(得分:0)

dbSetItem的类型为PropertyInfo,因为您调用了GetProperties()。它没有Add方法,这就是为什么如果找不到匹配方法,null GetMethod返回null的原因。< / p>

var dbSetItem = typesToRegister.First().PropertyType;

您无法将this传递给Invoke的第一个参数,它必须是DbSet<TypeEntity>类型的对象,您的数组也应该是object[](您可以通过其他东西,因为它会自动上转换。)

methodAdd.Invoke(dbSetItem, new object[] { entity });