博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Entity Framework 动态构造select表达式
阅读量:6589 次
发布时间:2019-06-24

本文共 2175 字,大约阅读时间需要 7 分钟。

hot3.png

扩展ef自动映射需要查询的字段 比如我们需要返回某些字段会采用如下的写法

但是发现每次都去写select如果字段很多不想去一个一个查询出来,就想指定一个dto的类型

他就能查询dto里边的字段,然后自动映射到dto里边去就可以减少很多工作量了

我们把lambda表达式提到外面去

这种可以,但是下面这种构建一个dto_user怎么都不行要报错

找了很久把表达式变成func就可以了

或者调用表达式树的Compile方法生成func当然也是一样的

有了这个就可以通过类型+反射动态构建查询的字段了

测试的原型

测试成功!很高兴于是去封装了一个通用的扩展方法!

用法:

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

但是很快就发现问题了,他居然是查询的全部!,然后那个查询需要字段的他居然是在内存中操作了,

每次都会查询全部字段出来

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

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

然后测试发现select如果传表达式树他会去解析成sql,他会转换成需要查询的字段sql

从返回的IQueryable接口就知道,他是会生成的sql的,但是如果我们传递的是Func呢

返回的却是IEnumerable,当然是在内存中操作的了,

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

因为func只能在里边当作方法去执行 而表达式数确可以得到很多东西比如参数返回值什么的 这也是他们的区别

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

不能直接传func

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

表达式树的学习:

这篇文章很好的解决了动态构建表达式树:

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

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}

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

转载于:https://my.oschina.net/u/2963604/blog/2050148

你可能感兴趣的文章
辗转相除法求最大公约数 php
查看>>
/lib64/libc.so.6: version `GLIBC_2.14' not found问题
查看>>
我的友情链接
查看>>
Struts2 校验框架学习笔记
查看>>
mysql配置文件参数详解 my.cnf
查看>>
Chrome DevTools
查看>>
cut、tr、wc、sort4
查看>>
Node.js 学习笔记--- (2)创建一个简单的博客工程
查看>>
使用php第三方包mpdf将网页装换成pdf文件【2】
查看>>
使用SoapUI生成wsdl文件客户端(二)
查看>>
优酷吞下土豆
查看>>
Linux设备驱动简析—PC重启源码分析
查看>>
python--1
查看>>
Gradle笔记
查看>>
怎么一步步编写简单的PHP的Framework(十九)
查看>>
spring与struts2 mvc共存web.xml简单配置
查看>>
常用禁止属性
查看>>
Android集成微信支付
查看>>
2015年终总结
查看>>
Spring常用注解
查看>>