如何使用反射在db中添加/更新数据

本文关键字:添加 更新 数据 db 何使用 反射 | 更新日期: 2023-09-27 18:14:27

我想用反射保存/更新我在db中的更改。我只有表名和字段id pk。我试着用反射来更新这个表…

 var table =(IQueryable)dbContext.ctx
      .GetType()
      .GetProperty(tableName)
      .GetValue(dbContext.ctx, null);

首先我有表和Iqueryable我不知道如何在db中更新我的表。

帮忙吗?

Thx

如何使用反射在db中添加/更新数据

这个答案是为了完整地说明您应该做什么。使用Set(非通用版本)是正确的方法。我知道你只知道tableName(甚至你的实体的Type都不知道)。但是Set需要Type。因此,您需要根据从tableName获得的PropertyInfoPropertyType找到该类型。在获得DbSet(非泛型)之后,您可以使用它的所有方法而不需要任何反射。传入的实体将只是object。下面是详细代码:

//we don't check if tableName can be resolved successfully for simplicity
//NOTE that there should be only one generic argument
//We know it's a DbSet<T>, with this we should have T
var entityType = dbContext.ctx.GetType().GetProperty(tableName)
                          .PropertyType.GetGenericArguments()[0];
//now obtain an instance of DbSet normally
var entities = dbContext.ctx.Set(entityType);
//all methods of DbSet are available now although the arguments are 
//object (not strongly typed).

你不需要DbSet<TEntity>吗?

var dbSet = (IDbSet<SomeEntity>)dbContext
                   .GetType()
                   .GetProperty(tableName, BindingFlags.Public | BindingFlags.Instance)
                   .GetValue(dbContext, null);

现在像在常规场景中那样调用DbSet<TEntity>方法,因为您有一个类型化的DbSet<T>

queryable没有多大帮助,因为正如您已经猜到的那样,它是关于查询而不是执行写操作回数据库。

OP说…

我不能使用DbSet,因为我从来不知道这个实体,我只知道表的名称。我做了一个后台办公室更改参考价值表,泛型接口..

然后,您的解决方案是使用反射甚至将实体添加到DbSet<TEntity>:

object dbSet = dbContext
                   .GetType()
                   .GetProperty(tableName, BindingFlags.Public | BindingFlags.Instance)
                   .GetValue(dbContext, null);
dbSet.GetMethod("Add", BindingFlags.Public | BindingFlags.Instance)
     .Invoke(new object[] { someEntityTypedAsObject }); 

或者您可以将DbSet<TEntity>存储为动态类型引用。这样,你就可以不带反射地调用它。这是性能和可读性的提升:

dynamic dbSet = dbContext
                       .GetType()
                       .GetProperty(tableName, BindingFlags.Public | BindingFlags.Instance)
                       .GetValue(dbContext, null);
dbSet.Add(someEntity);

您不应该在这里使用GetProperty,因为上下文可以包含使用Set/Set<T>方法创建的实体集(因此,在上下文类型中没有声明任何属性)。

第二种,假设实体类型是静态未知的,您需要将非泛型Set调用的结果强制转换为非泛型DbSet类型,并调用其Add/Remove/等方法。