动态lamada1.docx

上传人:b****7 文档编号:23399967 上传时间:2023-05-16 格式:DOCX 页数:6 大小:17.66KB
下载 相关 举报
动态lamada1.docx_第1页
第1页 / 共6页
动态lamada1.docx_第2页
第2页 / 共6页
动态lamada1.docx_第3页
第3页 / 共6页
动态lamada1.docx_第4页
第4页 / 共6页
动态lamada1.docx_第5页
第5页 / 共6页
点击查看更多>>
下载资源
资源描述

动态lamada1.docx

《动态lamada1.docx》由会员分享,可在线阅读,更多相关《动态lamada1.docx(6页珍藏版)》请在冰豆网上搜索。

动态lamada1.docx

动态lamada1

动态lamada

(1)

前言:

在DDD系列文章里面,我们在后台仓储里面封装了传递Lamada表达式的通用方法,类似这样:

publicvirtualIQueryableFind(Expressionbool>>express){Funcbool>lamada=express.Compile();returnUnitOfWork.context.Set().Where(lamada).AsQueryable();}通过前端传过来的Lamada表达式,直接放到Where条件里面查询。

那么问题来了,我们前端如何传入Lamada呢?

当然,有人说了,这个不用传啊,前端直接.Find(x=>x.Name==”abc”)这样写就好了啊。

确实,如果前端条件只有一个条件,你确实可以这样简单处理,但是实际开发的过程中,我们很多时候是需要传递多个参数,并且.Find(x=>x.Name==”abc”)这种写法也不利于方法的封装。

于是,我们神奇的动态Lamada诞生了。

一、再谈Lamada表达式

1、匿名委托

之前在介绍委托的时候我们介绍过一种特殊的匿名委托,它型如:

classProgram{privatedelegatevoidSayHello(stringname);staticvoidMain(string[]args){Say('张三',delegate(stringname){Console.WriteLine('你好,'+name);});Say('Zhangsan',delegate(stringname){Console.WriteLine('Hello,'+name);});}staticvoidSay(stringname,SayHellodTest){dTest(name);}}

也就是说,不用定义一种具体的委托方法去对应SayHello(stringname);,而直接delegate(stringname){}这样定义一种匿名的委托去执行,这样能减少部分定义具体方法的代码。

2、Lamada表达式进化史

了解了匿名委托的概念,我们来看看我们经常使用的Linq里面的扩展方法Where、Select等。

先来看看一般用法:

varlstTest=newListstring>();//.......业务逻辑varlstRes=lstTest.Where(x=>x.Contains('_'));

我们来将Where里面的x=>x.Contains(“_”)分解。

初级进化(最原始的匿名委托形式):

Funcstring,bool>oFunc=delegate(stringx){returnx.Contains('_');};lstRes=lstTest.Where(oFunc);

高级进化(型如Lamada,但还有匿名委托的影子):

Funcstring,bool>oFunc=(stringx)=>{returnx.Contains('_');};lstRes=lstTest.Where(oFunc);

究极进化(完完全全的Lamada)

Funcstring,bool>oFunc=x=>x.Contains('_');lstRes=lstTest.Where(oFunc);

有没有很强大,是不是一样一样的。

其实这样一看lamada就是匿名委托的缩略形式。

x=>x.Contains(“_”)表达式左边的表示Func里面的string类型变量,x.Contains(“_”)表示bool类型的返回值。

有了这份进化史,程序员再也不用担心面试官问我Lamada怎么回事了。

二、动态Lamada

与其叫动态Lamada,更加严谨一点应该叫动态Expression,因为拼接Lamada表达式用的基本都是Expression的类和方法。

博主习惯,暂且就叫它动态Lamada吧。

publicclassDTO_ORDER{publicstringTO_ORDER_ID{get;set;}publicstringORDER_NO{get;set;}publicstringORDER_NAME{get;set;}publicintORDER_STATUS{get;set;}}staticvoidMain(){//1.定义lamada的参数,型如我们常写的“x=>”ParameterExpressionm_Parameter=Expression.Parameter(typeof(DTO_ORDER),'x');//2.定义要使用lamada的属性成员(比如我们这里要对DTO_ORDER对象的ORDER_NO属性做筛选)MemberExpressionmember=Expression.PropertyOrField(m_Parameter,'ORDER_NO');//3.定义筛选的操作(是大于、等于、小于、like等)ExpressionexpRes=Expression.Equal(member,Expression.Constant('aaaa',member.Type));//4.将表达式转换为Lamada的表达式Expressionbool>>exprelamada=Expression.Lambdabool>>(expRes,m_Parameter);varlstRes=newList();for(vari=0;i10;i++){varoModel=newDTO_ORDER();oModel.ORDER_NO=i%2==0?

'aaaa':

'bbbb';lstRes.Add(oModel);}//5.将Expression表达式转换为Func委托,用于Where里面的参数varlamada=exprelamada.Compile();lstRes=lstRes.Where(lamada).ToList();}

以上就构造了一个查询List对象里面ORDER_NO属性等于aaaa的lamada表达式。

我们看看运行效果截图:

是不是已经得到了我们想要的表达式!

有没有很简单。

三、动态Lamada的使用

看到这里有人就郁闷了,为了得到x=>x.ORDER_NO==”aaaa”这种表达式,你绕了这么大一圈,有什么屌用?

直接lstRes=lstRes.Where(x=>x.ORDER_NO==”aaaa”);就能够搞定的事,你非要把简单问题复杂化。

其实不然,有一定编程经验的朋友肯定知道,一般我们前端传过来的查询参数肯定不会只有一个,当需要查询多个参数时需要我们构造一个统一的Lamada传递到后台;当然你也可以说,我将多个参数全部传递到后台,然后再后台使用IQueryable接口去过滤。

当然,这确实可行,但是别忘了我们封装Find(Expressionexp…)的意义,不就是为了简化方法么,从这点来说,构造动态Lamada非常必要。

1、通用Lamada表达式类

博主封装了一个简单操作(大于、等于、小于、like等)的动态Lamada类。

publicclassLamadaExtentionwhereDto:

new(){privateListm_lstExpression=null;privateParameterExpressionm_Parameter=null;publicLamadaExtention(){m_lstExpression=newList();m_Parameter=Expression.Parameter(typeof(Dto),'x');}  //构造表达式,存放到m_lstExpression集合里面publicvoidGetExpression(stringstrPropertyName,objectstrValue,ExpressionTypeexpressType){ExpressionexpRes=null;MemberExpressionmember=Expression.PropertyOrField(m_Parameter,strPropertyName);if(expressType==ExpressionType.Contains){expRes=Expression.Call(member,typeof(string).GetMethod('Contains'),Expression.Constant(strValue));}elseif(expressType==ExpressionType.Equal){expRes=Expression.Equal(member,Expression.Constant(strValue,member.Type));}elseif(expressType==ExpressionType.LessThan){expRes=Expression.LessThan(member,Expression.Constant(strValue,member.Type));}elseif(expressType==ExpressionType.LessThanOrEqual){expRes=Expression.LessThanOrEqual(member,Expression.Constant(strValue,member.Type));}elseif(expressType==ExpressionType.GreaterThan){expRes=Expression.GreaterThan(member,Expression.Constant(strValue,member.Type));}elseif(expressType==ExpressionType.GreaterThanOrEqual){expRes=Expression.GreaterThanOrEqual(member,Expression.Constant(strValue,member.Type));}//returnexpRes;m_lstExpression.Add(expRes);}//针对Or条件的表达式publicvoidGetExpression(stringstrPropertyName,Listobject>lstValue){ExpressionexpRes=null;MemberExpressionmember=Expression.PropertyOrField(m_Parameter,strPropertyName);foreach(varoValueinlstValue){if(expRes==null){expRes=Expression.Equal(member,Expression.Constant(oValue,member.Type));}else{expRes=Expression.Or(expRes,Expression.Equal(member,Expression.Constant(oValue,member.Type)));}}m_lstExpression.Add(expRes);}  //得到Lamada表达式的Expression对象publicExpressionbool>>GetLambda(){ExpressionwhereExpr=null;foreach(varexprinthis.m_lstExpression){if(whereExpr==null)whereExpr=expr;elsewhereExpr=Expression.And(whereExpr,expr);}if(whereExpr==null)returnnull;returnExpression.Lambda>(whereExpr,m_Parameter);}}//用于区分操作的枚举publicenumExpressionType{Contains,//likeEqual,//等于LessThan,//小于LessThanOrEqual,//小于等于GreaterThan,//大于GreaterThanOrEqual//大于等于}

2、使用场景

博主项目中有某一个页面,查询条件非常多,需要传递到后台很多参数。

先来看看页面:

来看后台webapi代码

publicobjectGet(intlimit,intoffset,stringstrBodyno,stringstrVin,stringstrOrderno,stringstrEngincode,stringstrOrderstatus,stringstrTranscode,stringstrVms,stringstrCarcode,stringstrImportStartdate,stringstrImportEnddate,stringstrSendStartdate,stringstrSendEnddate){//1.定义对象,传入泛型varoLamadaExtention=newLamadaExtention();//2.依次构造Lamada表达式if(!

string.IsNullOrEmpty(strBodyno)){oLamadaExtention.GetExpression('BODY_NO',strBodyno,ExpressionType.Contains);}if(!

string.IsNullOrEmpty(strVin)){oLamadaExtention.GetExpression('VIN',strVin,ExpressionType.Contains);}if(!

string.IsNullOrEmpty(strOrderno)){oLamadaExtention.GetExpression('ORDER_NO',strOrderno,ExpressionType.Contains);}if(!

string.IsNullOrEmpty(strEngincode)){oLamadaExtention.GetExpression('ENGIN_CODE',strEngincode,ExpressionType.Contains);}if(!

string.IsNullOrEmpty(strOrderstatus)){if(strOrderstatus.Contains(',')){varlstValue=strOrderstatus.Split(','.ToCharArray(),StringSplitOptions.RemoveEmptyEntries).ToList();varlstObj=newListobject>();lstValue.ForEach(x=>{lstObj.Add(Convert.ToInt16(x));});oLamadaExtention.GetExpression('ORDER_STATUS',lstObj);}else{oLamadaExtention.GetExpression('ORDER_STATUS',Convert.ToInt16(strOrderstatus),ExpressionType.Equal);}}if(!

string.IsNullOrEmpty(strTranscode)){oLamadaExtention.GetExpression('TRANS_CODE',strTranscode,ExpressionType.Contains);}if(!

string.IsNullOrEmpty(strVms)){oLamadaExtention.GetExpression('VMS_NO',strVms,ExpressionType.Contains);}if(!

string.IsNullOrEmpty(strCarcode)){oLamadaExtention.GetExpression('TM_MODEL_MATERIAL_ID',strCarcode,ExpressionType.Contains);}if(!

string.IsNullOrEmpty(strImportStartdate)){oLamadaExtention.GetExpression('CREATE_DATE',Convert.ToDateTime(strImportStartdate),ExpressionType.GreaterThanOrEqual);}if(!

string.IsNullOrEmpty(strImportEnddate)){oLamadaExtention.GetExpression('CREATE_DATE',Convert.ToDateTime(strImportEnddate),ExpressionType.LessThanOrEqual);}if(!

string.IsNullOrEmpty(strSendStartdate)){oLamadaExtention.GetExpression('OFFLINE_DATE_ACT',Convert.ToDateTime(strSendStartdate),ExpressionType.GreaterThanOrEqual);}if(!

string.IsNullOrEmpty(strSendEnddate)){oLamadaExtention.GetExpression('OFFLINE_DATE_ACT',Convert.ToDateTime(strSendEnddate),ExpressionType.LessThanOrEqual);}//3.得到需要的Lamada表达式Expressionvarlamada=oLamadaExtention.GetLambda();varlstRes=orderManager.Find(lamada).ToList();//4.得到BootstrapTable需要的对象varoRes=newPageRowData();      returnoRes;;}

仓储基类里面的find方法:

publicvirtualIQueryableFind(Expressionbool>>express){Funcbool>lamada=express.Compile();returnUnitOfWork.context.Set().Where(lamada).AsQueryable();}

四、小结

至此,所谓的动态Lamada就完了。

如果你之前用过,请一笑而过;当然如果你没用过,学习点新东西也是好的。

请不要嘲笑博主乱下定义,叫动态Lamada挺好的呢。

当然你可以叫动态Expression,动态Linq都行,不管叫什么,正确使用才是王道。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 面试

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1