//***********************************************************************//<copyrightfile="DynamicLinq.cs"company="">//Copyright(c).Allrightsreserved.//</copyright>//<summary>动态linq</summary>//***********************************************************************usingHh.Mes.Common.Json;usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Linq.Expressions;usingSystem.Reflection;namespaceHh.Mes.Common.Infrastructure{publicstaticclassDynamicLinq{publicstaticParameterExpressionCreateLambdaParam<T>(stringname){returnExpression.Parameter(typeof(T),name);}///<summary>///创建linq表达示的body部分///</summary>publicstaticExpressionGenerateBody<T>(thisParameterExpressionparam,FilterfilterObj){PropertyInfoproperty=typeof(T).GetProperty(filterObj.Key);//组装左边Expressionleft=Expression.Property(param,property);//组装右边Expressionright=null;if((property.PropertyType==typeof(int)||property.PropertyType==typeof(int?))||(property.PropertyType==typeof(short)||property.PropertyType==typeof(short?))||(property.PropertyType==typeof(long)||property.PropertyType==typeof(long?))||(property.PropertyType==typeof(decimal)||property.PropertyType==typeof(decimal?))||(property.PropertyType==typeof(double)||property.PropertyType==typeof(double?))){stringstype=property.PropertyType.ToString().ToLower();Expressionleftexp=property.PropertyType.ToString().IndexOf("Nullable")>=0?Expression.Property(left,"Value"):left;objectfilterValue=null;if(string.IsNullOrEmpty(filterObj.Value)){filterValue=0;}else{if(property.PropertyType==typeof(int)||property.PropertyType==typeof(int?)){filterValue=int.Parse(filterObj.Value);}elseif(property.PropertyType==typeof(short)||property.PropertyType==typeof(short?)){filterValue=short.Parse(filterObj.Value);}elseif(property.PropertyType==typeof(long)||property.PropertyType==typeof(long?)){filterValue=long.Parse(filterObj.Value);}elseif(property.PropertyType==typeof(decimal)||property.PropertyType==typeof(decimal?)){filterValue=decimal.Parse(filterObj.Value);}elseif(property.PropertyType==typeof(double)||property.PropertyType==typeof(double?)){filterValue=double.Parse(filterObj.Value);}//if(stype.IndexOf("int")>=0)//{filterValue=int.Parse(filterObj.Value);}//elseif(stype.IndexOf("short")>=0)//{filterValue=short.Parse(filterObj.Value);}//elseif(stype.IndexOf("long")>=0)//{filterValue=long.Parse(filterObj.Value);}//elseif(stype.IndexOf("decimal")>=0)//{filterValue=decimal.Parse(filterObj.Value);}//elseif(stype.IndexOf("double")>=0)//{filterValue=double.Parse(filterObj.Value);}}Typetype=filterValue.GetType();left=Expression.Call(leftexp,type.GetMethod("CompareTo",newType[]{type}),Expression.Constant(filterValue));right=Expression.Constant(0);}elseif(property.PropertyType==typeof(DateTime)||property.PropertyType==typeof(DateTime?)){if(filterObj.Contrast=="like"){Expressionleftexp=property.PropertyType==typeof(DateTime)?left:Expression.Property(left,"Value");filterObj.Contrast="==";if(filterObj.Value.Length==4){left=Expression.Call(Expression.Property(leftexp,"Year"),typeof(int).GetMethod("Equals",newType[]{typeof(int)}),Expression.Constant(int.Parse(filterObj.Value)));}elseif(filterObj.Value.Length==7){DateTimedate=Convert.ToDateTime(filterObj.Value);left=Expression.Call(Expression.Property(leftexp,"Year"),typeof(int).GetMethod("Equals",newType[]{typeof(int)}),Expression.Constant(date.Year)).And(Expression.Call(Expression.Property(leftexp,"Month"),typeof(int).GetMethod("Equals",newType[]{typeof(int)}),Expression.Constant(date.Month)));}else{DateTimedate=Convert.ToDateTime(filterObj.Value);left=Expression.Call(Expression.Property(leftexp,"Year"),typeof(int).GetMethod("Equals",newType[]{typeof(int)}),Expression.Constant(date.Year)).And(Expression.Call(Expression.Property(leftexp,"Month"),typeof(int).GetMethod("Equals",newType[]{typeof(int)}),Expression.Constant(date.Month))).And(Expression.Call(Expression.Property(leftexp,"Day"),typeof(int).GetMethod("Equals",newType[]{typeof(int)}),Expression.Constant(date.Day)));}right=Expression.Constant(true);}else{Expressionleftexp=property.PropertyType==typeof(DateTime)?left:Expression.Property(left,"Value");objectfilterValue=string.IsNullOrEmpty(filterObj.Value)?DateTime.Now:DateTime.Parse(filterObj.Value);left=Expression.Call(leftexp,typeof(DateTime).GetMethod("CompareTo",newType[]{typeof(DateTime)}),Expression.Constant(filterValue));right=Expression.Constant(0);}}elseif(property.PropertyType==typeof(string)){filterObj.Value=filterObj.Value.ToUpper();left=Expression.Call(left,typeof(string).GetMethod("ToUpper",newType[]{}));right=Expression.Constant((filterObj.Value));}elseif(property.PropertyType==typeof(bool)||property.PropertyType==typeof(bool?)){if(!string.IsNullOrEmpty(filterObj.Value)){if(filterObj.Value.ToLower().Equals("true")||filterObj.Value.ToLower().Equals("1")){filterObj.Value="true";}else{filterObj.Value="false";}}Expressionleftexp=property.PropertyType==typeof(bool)?left:Expression.Property(left,"Value");objectfilterValue=string.IsNullOrEmpty(filterObj.Value)?bool.Parse("true"):bool.Parse(filterObj.Value);left=Expression.Call(leftexp,typeof(bool).GetMethod("CompareTo",newType[]{typeof(bool)}),Expression.Constant(filterValue));right=Expression.Constant(0);}elseif(property.PropertyType==typeof(Guid)||property.PropertyType==typeof(Guid?)){Expressionleftexp=property.PropertyType==typeof(Guid)?left:Expression.Property(left,"Value");objectfilterValue=string.IsNullOrEmpty(filterObj.Value)?Guid.Parse("00000000-0000-0000-0000-000000000000"):Guid.Parse(filterObj.Value);left=Expression.Call(leftexp,typeof(Guid).GetMethod("CompareTo",newType[]{typeof(Guid)}),Expression.Constant(filterValue));right=Expression.Constant(0);}else{thrownewException("暂不能解析该Key的类型");}CheckFilterString(filterObj.JqContrast,property.PropertyType);//c.XXX=="XXX"Expressionfilter=Expression.Equal(left,right);//等于switch(filterObj.Contrast){case"<="://小于等于filter=Expression.LessThanOrEqual(left,right);break;case"<"://小于filter=Expression.LessThan(left,right);break;case">"://大于filter=Expression.GreaterThan(left,right);break;case">="://大于等于filter=Expression.GreaterThanOrEqual(left,right);break;case"!="://不等于filter=Expression.NotEqual(left,right);break;case"like"://包含filter=Expression.Call(left,typeof(string).GetMethod("Contains",newType[]{typeof(string)}),Expression.Constant(filterObj.Value));break;case"not like"://不包含filter=Expression.Not(Expression.Call(left,typeof(string).GetMethod("Contains",newType[]{typeof(string)}),Expression.Constant(filterObj.Value)));break;case"in"://属于varlExp=Expression.Constant(filterObj.Value.Split(',').ToList());//数组varmethodInfo=typeof(List<string>).GetMethod("Contains",newType[]{typeof(string)});//Contains语句filter=Expression.Call(lExp,methodInfo,left);break;case"not in"://不属于varlistExpression=Expression.Constant(filterObj.Value.Split(',').ToList());//数组varmethod=typeof(List<string>).GetMethod("Contains",newType[]{typeof(string)});//Contains语句filter=Expression.Not(Expression.Call(listExpression,method,left));break;case"begin with"://开始于filter=Expression.Call(left,typeof(string).GetMethod("StartsWith",newType[]{typeof(string)}),Expression.Constant(filterObj.Value));break;case"not begin with"://不开始于filter=Expression.Not(Expression.Call(left,typeof(string).GetMethod("StartsWith",newType[]{typeof(string)}),Expression.Constant(filterObj.Value)));break;case"end with"://结束于filter=Expression.Call(left,typeof(string).GetMethod("EndsWith",newType[]{typeof(string)}),Expression.Constant(filterObj.Value));break;case"not end with"://不结束于filter=Expression.Not(Expression.Call(left,typeof(string).GetMethod("EndsWith",newType[]{typeof(string)}),Expression.Constant(filterObj.Value)));break;case"null"://为空filter=Expression.Equal(left,Expression.Constant(string.Empty));break;case"not null"://不为空filter=Expression.NotEqual(left,Expression.Constant(string.Empty));break;}returnfilter;}privatestaticvoidCheckFilterString(stringp,Typetype){boolvalid=false;stringerrmsg=string.Format("{0}类型不支持{1}操作",type,p);stringtypeS=type.ToString();if(type==typeof(int)||type==typeof(int?)||type==typeof(decimal)||type==typeof(decimal?)||type==typeof(long)||type==typeof(long?)||type==typeof(short)||type==typeof(short?)||type==typeof(double)||type==typeof(double?)||type==typeof(DateTime)||type==typeof(DateTime?)){if(type==typeof(DateTime)||type==typeof(DateTime?)){valid=("eq,ne,lt,le,gt,ge,cn".Split(',').Contains(p));}else{valid=("eq,ne,lt,le,gt,ge".Split(',').Contains(p));}}elseif(type==typeof(string)){valid=("eq,ne,bw,bn,in,ni,ew,en,cn,nc,nu,nn".Split(',').Contains(p));}elseif(type==typeof(Guid)||type==typeof(Guid?)||type==typeof(bool)||type==typeof(bool?)){valid=("eq,ne".Split(',').Contains(p));}if(!valid){thrownewException(errmsg);};}publicstaticExpression<Func<T,bool>>GenerateTypeBody<T>(thisParameterExpressionparam,FilterfilterObj){return(Expression<Func<T,bool>>)(param.GenerateBody<T>(filterObj));}///<summary>///创建完整的lambda///</summary>publicstaticLambdaExpressionGenerateLambda(thisParameterExpressionparam,Expressionbody){//c=>c.XXX=="XXX"returnExpression.Lambda(body,param);}publicstaticExpression<Func<T,bool>>GenerateTypeLambda<T>(thisParameterExpressionparam,Expressionbody){return(Expression<Func<T,bool>>)(param.GenerateLambda(body));}publicstaticExpressionAndAlso(thisExpressionexpression,ExpressionexpressionRight){returnExpression.AndAlso(expression,expressionRight);}publicstaticExpressionOr(thisExpressionexpression,ExpressionexpressionRight){returnExpression.Or(expression,expressionRight);}publicstaticExpressionAnd(thisExpressionexpression,ExpressionexpressionRight){returnExpression.And(expression,expressionRight);}//系统已经有该函数的实现//publicstaticIQueryable<T>Where<T>(thisIQueryable<T>query,Expressionexpression)//{//Expressionexpr=Expression.Call(typeof(Queryable),"Where",new[]{typeof(T)},//Expression.Constant(query),expression);////生成动态查询//IQueryable<T>result=query.Provider.CreateQuery<T>(expr);//returnresult;//}publicstaticIQueryable<T>GenerateFilter<T>(thisIQueryable<T>query,stringfilterjson){if(!string.IsNullOrEmpty(filterjson)&&filterjson!="null"){varfilters=JsonHelper.Instance.Deserialize<IEnumerable<Filter>>(filterjson);varparam=CreateLambdaParam<T>("c");Expressionresult=Expression.Constant(true);foreach(varfilterinfilters){result=result.AndAlso(param.GenerateBody<T>(filter));}query=query.Where(param.GenerateTypeLambda<T>(result));}returnquery;}publicstaticExpression<Func<T,bool>>AndAlso<T>(thisExpression<Func<T,bool>>expr1,Expression<Func<T,bool>>expr2){varparameter=Expression.Parameter(typeof(T));varleftVisitor=newReplaceExpressionVisitor(expr1.Parameters[0],parameter);varleft=leftVisitor.Visit(expr1.Body);varrightVisitor=newReplaceExpressionVisitor(expr2.Parameters[0],parameter);varright=rightVisitor.Visit(expr2.Body);returnExpression.Lambda<Func<T,bool>>(Expression.AndAlso(left,right),parameter);}privateclassReplaceExpressionVisitor:ExpressionVisitor{privatereadonlyExpression_oldValue;privatereadonlyExpression_newValue;publicReplaceExpressionVisitor(ExpressionoldValue,ExpressionnewValue){_oldValue=oldValue;_newValue=newValue;}publicoverrideExpressionVisit(Expressionnode){if(node==_oldValue)return_newValue;returnbase.Visit(node);}}}}