如何动态添加过滤器针对的OData源LINQ查询在C# [英] How to dynamic add filters to a LINQ query against an Odata Source in C#

查看:226
本文介绍了如何动态添加过滤器针对的OData源LINQ查询在C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有类似如下

var query = (from x in NetworkDevices
where   
x.Name == "blabla1" ||
x.Name == "blabla2" 
select x );

和我跑这对一个OData的端点,所以它有效地被转换成以下网址

and i'm running it against an Odata endpoint, so it effectively gets translated into the following URL

https://targetserver/endpoint.svc/NetworkDevices()?$filter=Name eq 'blabla1' or Name eq 'blabla2'

所以我想动态添加那些大量的,其中过滤器...在C#中我可以只保留将它添加到我的查询,但这不是动态的。我想在运行时做到这一点。如果我是从Javascript调用这个,那么我可以很容易地只更新网址为好。

So i want to dynamically add lots of those where filters... In C# i can just keep adding it to my query, but that isn't dynamic. I want to do it at runtime. If i was calling this from Javascript, well i can easily just update the URL as well.

我的问题,是在C#中如何动态地这些过滤器添加到哪里条款。

My Question, is in C# how do i dynamically add these filters to the where clause.

在普通的旧LINQ(如LINQ 2的对象)我可以做这样的事情。

in plain old LINQ (like linq 2 objects) i could do something like this.

var machines = new string[] { "blabla1" , "blabla2" } ;
res1.Where ( x => machines.Contains(x.Name) ).ToArray()

和,将工作,但这并不对OData的端点工作,因为我得到这样的错误。

and that would work, but that doesn't work against the Odata Endpoint as i get an error like this.

方法'包含'不支持

所以我推测的唯一方法是动态的,编辑表达式树或一些补充这些过滤器。是否有人知道该怎么做?

So i presume the only way would be to dynamically , edit the expression tree or something to add those filters. Does anybody know how to do that?

推荐答案

以下一些环节,我发现一对夫妇的选择。其中之一是动态创建这成了泥潭,而迅速表达式树,另一种是手工打造的$过滤器。然而与.AddQueryOption添加它()。但是,如果已经有其他的where子句在这打破因为生成的URL现在有两个$过滤条目..所以我要做的就是把我的原始查询,然后抓住URL和查询字符串,并抢在$过滤器的查询,那么如果存在添加自己的动态的东西,并运行新的查询。这里是一个演示(在linqpad运行)

Following some other links , i found a couple of options. One would be to dynamically create the expression tree which became a quagmire rather quickly, the other is to build the $filter manually. However and add it with .AddQueryOption() . However if there are already other where clauses in the query this breaks since the resulting URL now has two $filter entries.. So what i do is take my original query, and then grab the URL and the querystring and grab the $filter , and then if it exists add my own dynamic stuff and run a new query. here is a demo (running in linqpad)

//Grab original query as a DataServiceQuery
DataServiceQuery<NetworkDevice> originalquery = (DataServiceQuery<NetworkDevice>) 
    (from x in NetworkDevices
    where   
    x.Type == "switch"
    select x);
//Get the HTTP QueryString
var querystr = (originalquery).RequestUri.Query;
var filter = System.Web.HttpUtility.ParseQueryString(querystr)["$filter"];

/* Create our own dynamic filter equivilant to 
    x.Name == "x" ||
    x.Name == "y" 
*/
string[] names = { "device1", "device2" };
StringBuilder sb = new StringBuilder();
sb.Append("(");
foreach (string s in names)
{
    sb.Append(String.Format("Name eq '{0}'",s));
    sb.Append(" or ");
}
sb.Remove(sb.Length - 4, 4);
sb.Append(")");
var dynamicfilter = sb.ToString();
// If there was an original filter we'll add the dynamic one with AND , otherwise we'll just use the dynamicone
var newfilter = dynamicfilter;
if ( filter != null && filter.Trim() != string.Empty )
{
newfilter = filter + " and " + newfilter;
}
newfilter.Dump();


var finalquery = 
    (from x in NetworkDevices.AddQueryOption("$filter",newfilter)
    select x).Take(50);

finalquery.Dump();

这篇关于如何动态添加过滤器针对的OData源LINQ查询在C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆