Entity Framework 动态构造select表达式

扩展ef自动映射须要查询的字段 好比咱们须要返回某些字段会采用以下的写法html

可是发现每次都去写select若是字段不少不想去一个一个查询出来,就想指定一个dto的类型sql

他就能查询dto里边的字段,而后自动映射到dto里边去就能够减小不少工做量了数据库

咱们把lambda表达式提到外面去express

这种能够,可是下面这种构建一个dto_user怎么都不行要报错学习

找了好久把表达式变成func就能够了测试

或者调用表达式树的Compile方法生成func固然也是同样的.net

有了这个就能够经过类型+反射动态构建查询的字段了code

测试的原型htm

测试成功!很高兴因而去封装了一个通用的扩展方法!对象

用法:

这样就会自动映射DTO_User了,写出来了仍是很激动

可是很快就发现问题了,他竟然是查询的所有!,而后那个查询须要字段的他竟然是在内存中操做了,

每次都会查询所有字段出来

其实这个扩展方法实现了动态拷贝,能够做为解决这个问题的第二个步骤,把须要的字段查询出来后

在进行动态拷贝,平时进行对象转化的时候也能够直接用

而后测试发现select若是传表达式树他会去解析成sql,他会转换成须要查询的字段sql

从返回的IQueryable接口就知道,他是会生成的sql的,可是若是咱们传递的是Func呢

返回的倒是IEnumerable,固然是在内存中操做的了,

数据库查询只有IEnumerable才回执行到数据库 IQueryable只拼接sql

由于func只能在里边看成方法去执行 而表达式数确能够获得不少东西好比参数返回值什么的 这也是他们的区别

想要真正实现自动映射到DTO,并且只查询的仍是那几个字段,那么这里要想办法动态建立表达式树,

不能直接传func

这就须要了解ef内部是怎么解析的这个表达式树,还有表达式树是怎么动态生成的了

表达式树的学习:http://www.cnblogs.com/li-peng/p/3154381.html

这篇文章很好的解决了动态构建表达式树:http://www.cnblogs.com/JimmyZheng/archive/2012/02/23/2364154.html

http://blog.csdn.net/cauchy8389/article/details/23529857

http://bbs.csdn.net/topics/390790484

http://bbs.csdn.net/topics/390813750

查了2天资料终于找到解决方案了使用MemberInitExpression就能够动态构建

https://msdn.microsoft.com/zh-cn/library/system.linq.expressions.memberinitexpression.aspx

msdn上面的资料

class Animal { public string Species {get; set;} public int Age {get; set;} }

public static void CreateMemberInitExpression() { System.Linq.Expressions.NewExpression newAnimal = System.Linq.Expressions.Expression.New(typeof(Animal));

System.Reflection.MemberInfo speciesMember =
    typeof(Animal).GetMember("Species")[0];
System.Reflection.MemberInfo ageMember =
    typeof(Animal).GetMember("Age")[0];

// Create a MemberBinding object for each member
// that you want to initialize.
System.Linq.Expressions.MemberBinding speciesMemberBinding =
    System.Linq.Expressions.Expression.Bind(
        speciesMember,
        System.Linq.Expressions.Expression.Constant("horse"));
System.Linq.Expressions.MemberBinding ageMemberBinding =
    System.Linq.Expressions.Expression.Bind(
        ageMember,
        System.Linq.Expressions.Expression.Constant(12));

// Create a MemberInitExpression that represents initializing
// two members of the 'Animal' class.
System.Linq.Expressions.MemberInitExpression memberInitExpression =
    System.Linq.Expressions.Expression.MemberInit(
        newAnimal,
        speciesMemberBinding,
        ageMemberBinding);

Console.WriteLine(memberInitExpression.ToString());

// This code produces the following output:
//
// new Animal() {Species = "horse", Age = 12}

} 改进下:使用参数来赋值

相关文章
相关标签/搜索