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

如何在C#中针对Odata源动态添加filter到LINQ查询分享

时间:2023-04-10 21:56:21 C#

C#学习教程:HowtodynamicallyaddfiltertoLINQqueryforOdatasourceinC#名称=="blabla1"||x.Name=="blabla2"选择x);我正在针对Odata端点运行它,因此它有效地转换为以下URLhttps://targetserver/endpoint.svc/NetworkDevices()?$filter=Nameeq'blabla1'或Nameeq'blabla2'所以我想动态添加许多过滤器...在C#中,我可以继续添加到我的查询中,但它不是动态的。我想在运行时执行此操作。如果我从Javascript调用它,那么我也可以轻松更新URL。我的问题是如何将这些过滤器动态添加到C#中的where子句。在普通的旧LINQ(如linq2对象)中,我可以做这样的事情。varmachines=newstring[]{"blabla1","blabla2"};res1.Where(x=>machines.Contains(x.Name)).ToArray()这可行,但这不适用于Odata端点,因为我收到这样的错误。不支持“包含”方法,所以我认为唯一的方法是通过编辑表达式树或其他方式动态添加这些过滤器。有谁知道如何做到这一点?通过其他一些链接,我找到了几个选项。一种是动态创建表达式树,很快就陷入泥潭,另一种是手动构建$filter。但是,使用.AddQueryOption()添加它。但是,如果查询中已经有其他where子句,这会中断,因为生成的URL现在有两个$filter条目。所以我要做的是获取原始查询,然后获取URL和查询字符串并获取$filter,然后如果它存在则添加我自己的动态内容并运行新查询。这是一个演示(在linqpad中运行)//GraboriginalqueryasaDataServiceQueryDataServiceQueryoriginalquery=(DataServiceQuery)(fromxinNetworkDeviceswherex.Type=="switch"selectx);//获取HTTPQueryStringvarquerystr=(originalquery).RequestUri.Query;varfilter=System.Web.HttpUtility.ParseQueryString(querystr)["$filter"];/*创建我们自己的动态过滤器,相当于x.Name=="x"||x.Name=="y"*/string[]names={"device1","device2"};StringBuildersb=newStringBuilder();sb.Append("(");foreach(stringsinnames){sb.Append(String.Format("Nameeq'{0}'",s));sb.Append("or");}sb.Remove(sb.Length-4,4);sb.Append(")");vardynamicfilter=sb.ToString();//如果有原始过滤器,我们将使用AND添加动态过滤器,否则我们将只使用动态过滤器varnewfilter=dynamicfilter;if(filter!=null&&filter.Trim()!=string.Empty){newfilter=filter+"and"+newfilter;}newfilter.Dump();变量finalquery=(fromxinNetworkDevices.AddQueryOption("$filter",newfilter)选择x).Take(50);finalquery.Dump();下面是我用的ExpressionVistor的一个例子,Contains转OrElse:以上是C#学习教程:如何为LINQ动态添加过滤器查询和共享C#中Odata源的所有内容。如果对你有用,需要了解更多C#学习教程,希望你多多关注——publicclassWhereContainsTreeModifier:ExpressionVisitor{varmember=methodCall.ObjectasMemberExpression;varobjectMember=Expression.Convert(成员,typeof(object));vargetterLambda=Expression.Lambda>(objectMember);vargetter=getterLambda.Compile();varlist=(IEnumerable)getter();表达式结果=空;foreach(列表中的对象项){varequal=Expression.Equal(methodCall.Arguments[0],Expression.Constant(item));如果(结果==null)结果=等于;否则result=Expression.OrElse(result,equal);}结果=Expression.Lambda(lambda.Type,result,lambda.Parameters);返回结果;}protectedoverrideExpressionVisitLambda(Expressionnode){if((node.BodyasMethodCallExpression).Method.Name=="Contains")returnTranslateContains(node);否则返回节点;,不代表立场,如涉及侵权,请点击右侧联系管理员删除如转载请注明出处: