应无所住,而生其心
排名
1
文章
860
粉丝
112
评论
163
net core webapi post传递参数
庸人 : 确实坑哈,我也是下班好了好几次,发现后台传递对象是可以的,但...
百度编辑器自定义模板
庸人 : 我建议换个编辑器,因为现在百度富文本已经停止维护了,用tinymec...
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术

扩展ef自动映射需要查询的字段(表达式树Expression),动态构建返回值

10977人阅读 2019/3/29 10:55 总访问:5185825 评论:1 收藏:0 手机
分类: EF

Entity Framework 动态构造select表达式

比如我们需要返回某些字段会采用如下的写法

但是发现每次都去写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内部是怎么解析的这个表达式树,还有表达式树是怎么动态生成的了


使用MemberInitExpression就可以动态构建需要的表达式树


msdn上面的资料

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

  1. class Animal
  2. {
  3.     public string Species {getset;}
  4.     public int Age {getset;}
  5. }
  6.  
  7. public static void CreateMemberInitExpression()
  8. {
  9.     System.Linq.Expressions.NewExpression newAnimal =
  10.         System.Linq.Expressions.Expression.New(typeof(Animal));
  11.  
  12.     System.Reflection.MemberInfo speciesMember =
  13.         typeof(Animal).GetMember("Species")[0];
  14.     System.Reflection.MemberInfo ageMember =
  15.         typeof(Animal).GetMember("Age")[0];
  16.  
  17.     // Create a MemberBinding object for each member
  18.     // that you want to initialize.
  19.     System.Linq.Expressions.MemberBinding speciesMemberBinding =
  20.         System.Linq.Expressions.Expression.Bind(
  21.             speciesMember,
  22.             System.Linq.Expressions.Expression.Constant("horse"));
  23.     System.Linq.Expressions.MemberBinding ageMemberBinding =
  24.         System.Linq.Expressions.Expression.Bind(
  25.             ageMember,
  26.             System.Linq.Expressions.Expression.Constant(12));
  27.  
  28.     // Create a MemberInitExpression that represents initializing
  29.     // two members of the 'Animal' class.
  30.     System.Linq.Expressions.MemberInitExpression memberInitExpression =
  31.         System.Linq.Expressions.Expression.MemberInit(
  32.             newAnimal,
  33.             speciesMemberBinding,
  34.             ageMemberBinding);
  35.  
  36.     Console.WriteLine(memberInitExpression.ToString());
  37.  
  38.     // This code produces the following output:
  39.     //
  40.     // new Animal() {Species = "horse", Age = 12}
  41. }


改进下:使用参数来赋值


 未完待续。。。



欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739。有需要软件开发,或者学习软件技术的朋友可以和我联系~(Q:815170684)

评价

人生若只如初见

2019/4/4 17:03:29

收藏下

扩展mvc实现model直接传递匿名对象

如果我们直接通过model传递匿名对象,是不行滴后台通过model传递一个匿名对象publicActionResultIndex() { returnView(ne...

根据委托和lamdba表达式扩展方法

lamdba表达式ForEach扩展方法:public static void GetForEach<T>(this IEnumerable<T> list, Action<T>...

表达式树+反射扩展ef实现动态排序。List动态排序

我们在显示表格的时候经常会在点击表头的时候实现排序,当然很多前端的框架都实现了当前页的页面排序,直接配置一下就行了...

推荐Visual Studio好用的扩展插件(不定时更新)

嗨咯,大家好。什么是扩展?扩展是可以允许你在 Visual Studio 中进行自定义并增强在其中的体验的附加项,通过添加新功能或...

ef扩展反射实现动态排序+表达式树

现在各种网站上的表格可以通过点击排头来实现排序例如:今天我就来一探究竟,这是怎么实现的呢?具体步骤:我通过写扩展方...

表达式树+反射+扩展方法实现动态排序效果

后台代码如下:方法1:逐个判断 -->缺点:代码重复,体验感差 if(sort.ToLower()=="max") { if(sortway==...

.net Core3.0在Ubuntu 16.04上面的部署(Supervisor+nginx)(扩展docker)

前 言Linux 随着Linux越来越流行,本人一个.net程序员也多次研究linux与.net的相关产品,以及中间件的使用方式。So今天给...

字符串扩展方法

获取字符串的实际长度(按单字节) publicstaticintGetRealLength(thisstringsource) { returnSystem.Text.Encoding.Defau...

验证合法性扩展方法

Email格式是否合法 publicstaticboolIsEmail(thisstringsource) { returnRegex.IsMatch(source,@"^\w+((-\w+)|(\.\...

扩展markdown增加mermaid支持画图

我看网上没有什么资料,只有说怎么去用它,没有说怎么才能用它。那就自己慢慢研究在让markdown支持,要自己实现这个必须要...

c扩展方法简单介绍

可以不用继承就可以给一个类增加方法!语法: Public static class 类名 { //你想添加的扩展方法 Public static ...

list扩展方法ForEach原理(where,FirstOrDefault同理!)

//ForEach的原理就是使用循环 //委托使用循环 publicstaticvoidMyForEach<T>(thisList<T>item,Action<T...

特性扩展实体对象验证、枚举验证值是否正确

如果实体属性字段过多,几十,上百个,如果我们每个字段都去判断的话很麻,代码量很大,我们可以采用特性加枚举进行验证:1、...

Mybatis的SQL构建7 小小扩展+springboot

pom.xml的依赖,我是直接在spring.io官方下的,这样避免依赖冲突<!--jdbc--> <dependency> <groupId>o...

nlog扩展官方文档

https://nlog-project.org/2015/06/30/extending-nlog-is-easy.html