当前位置: 首页 > 编程语言 > C#

如何使用Expression.Call在方法调用中嵌套方法调用Share

时间:2023-04-10 20:36:26 C#

如何使用Expression.Call在方法调用中嵌套方法调用DateTime转String。尽管我曾尝试将一个表达式的结果放入另一个表达式,但我惨遭失败。代码来自这个问题的最佳答案jqgridwithasp.netwebmethodandjsonusingsorting,paging,searchingandLINQ-但需要动态运算符。假设我从问题中得到以下方法作为StringExtension:string[]properties=source.Split('.');表达式表达式=p;类型type=p.Type;foreach(varpropinproperties){varproperty=type.GetProperty(prop);if(property==null)thrownewArgumentException("无效表达式","源");表达式=表达式.MakeMemberAccess(表达式,属性);type=property.PropertyType;}返回(成员表达式)表达式;所以我从后来适用于DateTime方法的问题中得到了以下内容。publicvirtualExpressionCreateExpression(stringsearchField,stringsearchString,stringsearchOper){Expressionexp=null;varp=Expression.Parameter(typeof(T),"p");表达式propertyAccess=searchField.ToMemberExpression(p);switch(searchOper){case"bw":exp=Expression.Call(propertyAccess,typeof(string).GetMethod("StartsWith",newType[]{typeof(string)}),Expression.Constant(searchString));休息;//我的新代码case"cn":if(propertyAccess.Type==typeof(DateTime)){//我的错误逻辑-来自JonSkeet下面的回答ExpressiontoStringCall=Expression.Call(propertyAccess,"ToString",null,new[]{Expression.Constant("D")});ExpressioncontainsCall=Expression.Call(toStringCall,"Contains",null,new[]{Expression.Constant(searchString)});exp=containsCall;}else{//不变exp=Expression.Call(propertyAccess,typeof(string).GetMethod("Contains",newType[]{typeof(string)}),Expression.Cons坦(搜索字符串));}休息;case"ew":exp=Expression.Call(propertyAccess,typeof(string).GetMethod("EndsWith",newType[]{typeof(string)}),Expression.Constant(searchString));休息;case"gt":exp=Expression.GreaterThan(propertyAccess,Expression.Constant(searchString,propertyAccess.Type));休息;case"ge":exp=Expression.GreaterThanOrEqual(propertyAccess,Expression.Constant(searchString,propertyAccess.Type));休息;case"lt":exp=Expression.LessThan(propertyAccess,Expression.Constant(searchString,propertyAccess.Type));休息;case"le":exp=Expression.LessThanOrEqual(propertyAccess,Expression.Constant(searchString,propertyAccess.Type));休息;case"eq":exp=Expression.Equal(propertyAccess,Expression.Constant(searchString.ToType(propertyAccess.Type),propertyAccess.Type));休息;案例“ne”:exp=Expression.NotEqual(propertyAccess,Expression.Constant(searchString,propertyAccess.Type));休息;默认值:返回空值;}return(Expression)Expression.Lambda(exp,p);我得到以下异常LINQtoEntitiesdoesnotrecognizethemethod'System.StringToString(System.String)'method,andthismethodcannotbeconvertedtoastoreexpression。我怀疑你想要这样的东西(从以前的版本中修复):usingSystem;使用System.Linq.Expressions;publicclassPerson{publicDateTimeDateOfBirth{get;放;}}publicclassTest{staticvoidMain(){varexpr=Foo("DateOfBirth","1976");Personp=newPerson{DateOfBirth=newDateTime(1976,6,19)};Console.WriteLine(expr.Compile()(p));}staticExpression>Foo(stringpropertyName,stringsearchValue){ParameterExpressionparameter=Expression.Parameter(typeof(T),"x");表达式属性=Expression.Property(parameter,propertyName);表达式toStringCall=Expression.Call(property,"ToString",null,new[]{Expression.Constant("D")});ExpressioncontainsCall=Expression.Call(toStringCall,"Contains",null,new[]{Expression.Constant(searchValue)});返回表达式。Lambda>(containsCall,参数);}}请注意,“null”值表示它是一个非泛型方法调用。试试这个代码...CallToExpression(...)...例如。ToExpression(NULL,Product.Name,"==","Test");这里。Product.Name是一个嵌套的属性..以上是C#学习教程:如何使用Expression.Call在方法的调用中嵌套对方法的调用。全部内容分享出来,如果对大家有用,需要进一步了解C#希望大家多多关注教程——publicstaticExpression>ToExpression(stringandOrOperator,stringpropName,stringopr,stringvalue,Expression>expr=null){表达式>func=null;尝试{ParameterExpressionparamExpr=Expression.Parameter(typeof(T));vararrProp=propName.Split('.').ToList();表达式binExpr=null;字符串部分名称=string.Empty;arrProp.ForEach(x=>{ExpressiontempExpr=null;partName=partName.IsNull()?x:partName+"."+x;if(partName==propName){varmember=NestedExprProp(paramExpr,partName);vartype=member.Type.Name=="Nullable`1"?Nullable.GetUnderlyingType(member.Type):member.Type;tempExpr=ApplyFilter(opr,member,Expression.Convert(ToExprConstant(type,value),member.Type));}elsetempExpr=ApplyFilter("!=",NestedExprProp(paramExpr,partName),Expression.Constant(null));if(binExpr!=null)binExpr=Expression.AndAlso(binExpr,tempExpr);否则binExpr=tempExpr;});表达式>innerExpr=Expression.Lambda>(binExpr,paramExpr);if(expr!=null)innerExpr=(andOrOperator.IsNull()||andOrOperator=="And"||andOrOperator=="AND"||andOrOperator=="&&")?innerExpr.And(expr):innerExpr.Or(expr);func=innerExpr;}catch{}返回函数;}privatestaticMemberExpressionNestedExprProp(Expressionexpr,stringpropName){string[]arrProp=propName.Split('.');intarrPropCount=arrProp.Length;返回(arrPropCount>1)?Expression.Property(NestedExprProp(expr,arrProp.Take(arrPropCount-1).Aggregate((a,i)=>a+"."+i)),arrProp[arrPropCount-1]):Expression.Property(expr,道具名称);}privatestaticExpressionToExprConstant(Typeprop,stringvalue){if(value.IsNull())returnExpression.Constant(value);对象val=null;switch(prop.FullName){case"System.Guid":val=value.ToGuid();休息;默认值:val=Convert.ChangeType(值,Type.GetType(prop.FullName));休息;}返回Expression.Constant(val);}privatestaticExpressionApplyFilter(stringopr,Expressionleft,Expressionright){ExpressionInnerLambda=null;switch(opr){case"==":case"=":InnerLambda=Expression.Equal(left,right);休息;case"":InnerLambda=Expression.GreaterThan(左,右);休息;case">=":InnerLambda=Expression.GreaterThanOrEqual(left,right);休息;case">PropExpr(stringPropName){ParameterExpressionparamExpr=Expression.Parameter(typeof(T));vartempExpr=Extentions.NestedExprProp(paramExpr,PropName);返回Expression.Lambda>(Expression.Convert(Expression.Lambda(tempExpr,paramExpr).Body,typeof(object)),paramExpr);}publicstaticIQueryOverOrderBy(thisIQueryOverCollection,stringsidx,stringsord){返回sord=="asc"?Collection.OrderBy(NHibernate.Criterion.Projections.Property(sidx)).Asc:Collection.OrderBy(NHibernate.Criterion.Projec}publicstaticExpression>And(thisExpression>expr1,Expression>expr2){varinvokedExpr=Expression.Invoke(expr2,expr1.Parameters.Cast());返回Expression.Lambda>(Expression.AndAlso(expr1.Body,invokedExpr),expr1.Parameters);}publicstaticExpression>Or(thisExpression>expr1,Expression>expr2){varinvokedExpr=Expression.Invoke(expr2,expr1.Parameters.Cast());返回Expression.Lambda>(Expression.OrElse(expr1.Body,invokedExpr),expr1.Parameters);}本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如有转载请注明出处: