Inv*_*nda 5 c# entity-framework system.reflection
在下面的代码中, 的类型domainObject有所不同(但以 结尾DO,然后我修剪它以获得相应的表名)。有了表的名称和它的类型,我想tableName用来自domainObject. 因此,我必须首先在表中找到相同的 POCOID来覆盖它。这是到目前为止的代码:
public void Update(object domainObject)
{
Type type = domainObject.GetType();
string tableName = type.Name.Substring(0, type.Name.Length - 2);
PropertyInfo tableProp = typeof(MyDbContext).GetProperty(tableName);
Type tableType = tableProp.PropertyType;
Type pocoType = tableType.GetGenericArguments()[0];
int id = (int)type.GetProperty("ID").GetValue(domainObject);
using (var context = new MyDbContext())
{
object table = tableProp.GetValue(context);
MethodInfo singleMethod = tableType.GetMethod("Single");
}
}
Run Code Online (Sandbox Code Playgroud)
通常,知道实际的表而不仅仅是它的类型,我现在会通过
var poco = context.TableName.Single(item => item.ID == id);
Run Code Online (Sandbox Code Playgroud)
这里有2个问题:
(1)Single是一种扩展方法。
(2) 我不知道如何以 an 的形式获取 lambda 表达式object以将其传递给Invokeof Single。
有什么办法可以用 Reflection 做到这一点,还是我必须解决这个问题?(例如,我可以遍历项目table并手动检查[这会将数据库中的所有内容加载到内存中,因此应该避免],或者可能配置 EF 以执行某种“覆盖”,只要我只是Add和对象ID如果可能,已经存在)。即使假设我可以解决这个问题,我仍然想知道这个问题的明确答案,因为它对我来说非常有趣!
如果您想使用反射并通过 ID 查找给定实体,如果 ID 是主键,这相当简单,因为这就是您所要做的:
object entity = context.Set(domainObject.GetType()).Find(id);
Run Code Online (Sandbox Code Playgroud)
如果您的属性不是主键,那么您需要按如下方式操作:
ParameterExpression p = Expression.Parameter(domainObject.GetType());
Expression property = Expression.Property(p, "ID");
Expression c = Expression.Constant(id);
Expression body = Expression.Equal(property, c);
Expression exp = Expression.Lambda(body, new ParameterExpression []{ p });
MethodInfo singleMethod = typeof(Queryable).GetMethods()
.Single(m => m.Name == "Single" && m.GetParameters().Count() == 2)
.MakeGenericMethod(domainObject.GetType());
DbSet dbSet = context.Set(domainObject.GetType());
object entity = singleMethod.Invoke(null, new object[]{ dbSet, exp });
Run Code Online (Sandbox Code Playgroud)
首先使用Expression类构建将传递给Single方法的表达式(在您的情况下,这将是p => p.ID == id)。然后Single从Queryable类中搜索正确的方法。最后一件事是使用适当的参数调用此方法。这样您就可以使用 .linq 进行任何 linq 查询Reflection。