ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

c# – 使用Reflection动态地向Entity Framework添加对象

2019-06-12 10:57:28  阅读:198  来源: 互联网

标签:c entity-framework system-reflection


在下面的代码中,domainObject的类型各不相同(但以DO结尾,然后我修剪它以获得相应的表名).拥有表的名称及其类型,我想更新一个现有对象 – 它的名称与由于EF的tableName相同 – 在数据库中使用来自domainObject的新属性值.因此,我必须首先在表中找到具有相同ID的POCO来覆盖它.这是到目前为止的代码:

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

通常,知道实际的表而不仅仅是它的类型,我现在将获得POCO via

var poco = context.TableName.Single(item => item.ID == id);

这里有两个问题:

(1)Single是一种扩展方法.

(2)我不知道如何以对象的形式获取lambda表达式以将其传递给Invoke of Single.

有什么方法可以用Reflection完成这项工作,还是我必须解决这个问题? (例如,我可以遍历表中的项目并手动检查[将从DB加载到内存中的所有内容,因此应该避免],或者可以将EF配置为在我添加和时执行某种“覆盖”如果可能的话,其ID已存在的对象).即使我认为我可以解决这个问题,我仍然想知道这个问题的确切答案,因为它对我来说非常有趣!

解决方法:

如果你想使用反射并按ID查找给定的实体,那么如果ID是主键,这很简单,因为这就是你所要做的:

object entity = context.Set(domainObject.GetType()).Find(id);

如果您的属性不是主键,则需要按如下方式执行:

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

首先使用Expression类构建将传递给Single方法的表达式(在您的情况下,这将是p => p.ID == id).然后从Queryable类中搜索正确的Single方法.最后一件事是使用适当的参数调用此方法.这样,您可以使用Reflection执行任何linq查询.

标签:c,entity-framework,system-reflection
来源: https://codeday.me/bug/20190612/1225353.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有