c# - 如何在 C# 中针对 Odata 源向 LINQ 查询动态添加过滤器

标签 c# linq wcf-data-services odata

我有如下查询

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

我正在针对 Odata 端点运行它,因此它有效地转换为以下 URL

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

所以我想动态添加很多过滤器...在 C# 中,我可以继续将它添加到我的查询中,但这不是动态的。我想在运行时做。如果我从 Javascript 调用它,那么我也可以轻松地更新 URL。

我的问题是在 C# 中如何将这些过滤器动态添加到 where 子句。

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

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

这会起作用,但对 Odata 端点不起作用,因为我收到这样的错误。

不支持“包含”方法

所以我认为唯一的方法是动态地编辑表达式树或添加这些过滤器。有人知道怎么做吗?

最佳答案

通过其他一些链接,我找到了几个选项。一种是动态创建表达式树,但很快就陷入困境,另一种是手动构建 $filter。但是,并使用 .AddQueryOption() 添加它。但是,如果查询中已经有其他 where 子句,那么这会中断,因为生成的 URL 现在有两个 $filter 条目。所以我要做的是采用我的原始查询,然后获取 URL 和查询字符串并获取 $filter ,然后然后如果它存在添加我自己的动态内容并运行一个新查询。这是一个演示(在 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();

关于c# - 如何在 C# 中针对 Odata 源向 LINQ 查询动态添加过滤器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15777219/

相关文章:

.net - 我可以(安全地)在 ADO.NET 数据服务中使用 ThreadStatic 属性吗?

wcf-data-services - WCF DataService 不支持预检选项请求?

c# - 如何在asp.net中使用Page_Init

c# - 使用 where 语句的 LINQ 非常慢

c# - 为什么这里不支持隐藏

c# - LINQ 计数字符外观

c# - 比较两个集合并从一个集合中添加/删除以使它们匹配

C# - 如何解析 http header multipart

c# - 将代码与空格对齐时阻止 IDE0055 样式分析器

c# - 如何使用 C# 从 Kafka 获取主题列表