如何使用反射在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
这个答案是为了完整地说明您应该做什么。使用Set
(非通用版本)是正确的方法。我知道你只知道tableName
(甚至你的实体的Type
都不知道)。但是Set
需要Type
。因此,您需要根据从tableName
获得的PropertyInfo
的PropertyType
找到该类型。在获得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
/等方法。