OData“列表中的ID”查询
我有一个OData服务,我试图通过ID列表进行筛选; SQL的等价物会是这样的:
SELECT * FROM MyTable WHERE TableId IN (100, 200, 300, 400)
我试图过滤的属性是键入为Int32。 我试过以下,这给我一个错误“操作员添加”与操作数types“Edm.String”和“Edm.Int32”不兼容:
string ids = ",100,200,300,400,"; from m in provider.Media where ids.Contains("," + t.media_id + ",")
以及
string ids = ",100,200,300,400,"; from m in provider.Media where ids.Contains("," + t.media_id.ToString() + ",")
和
string ids = ",100,200,300,400,"; from m in provider.Media where ids.Contains("," + Convert.ToString(t.media_id) + ",")
和
string ids = ",100,200,300,400,"; from m in provider.Media where ids.Contains(string.Concat(",", t.media_id, ","))
正如你所看到的,目前我正在使用LINQ来查询服务。
有没有办法我可以做我想做的,或者我坚持构build一个文本filter,并使用AddQueryOption,迭代通过列表,并手动添加“或media_id eq 100”子句?
试试这个
var ids = new [] { 100, 200, 300 } ; var res = from m in provider.Media from id in ids where m.media_id == id select m;
msdn在查询DataServices上有一个全面的描述。
另一种方法是
var results = provider.Media .AddQueryOption("$filter", "media_id eq 100");
而且由于OData不支持IN
语句,所以你会得到像这样的过滤条件
.AddQueryOption("$filter", "(media_id eq 100) or (media_id eq 200 ) or ...");
你可以使用循环或linq来构buildSelect
和string.Join
:
var ids = new [] { 100, 200, 300 }; var filter = string.Join(" or ", ids.Select(i=> $"(media_id eq {i})")); var results = provider.Media.AddQueryOption("$filter", filter);
更新:有过滤操作field=["a","b"]
但是它意味着不同的东西。
更新2:在OData V4中,有lambdaexpression式any
和all
,与数组literal ["a", "b"]
配对,他们可能会工作in
但我没有拿出在OData.org的例子v4端点上的工作语法
为了扩大vittore的答案(其中第二部分是正确的答案),我写了一个类似于下面的演示项目的东西:
var filterParams = ids.Select(id => string.Format("(media_id eq {0})", id)); var filter = string.Join(" or ", filterParams); var results = provider.Media.AddQueryOption("$filter", filter).Execute().ToList();
这不是优雅的,你不会希望使用这个大的ID列表(> ~60),但它会做的伎俩。
如果我们需要更多的50个或60个ID,扩展MCattle的build议,那么我们build议在两个或多个并行调用中进行并行处理,并将它们添加到并发字典或类似的服务器上。 虽然这增加了对服务器的呼叫数量,但是由于我们正在慢慢转移到云环境,所以我认为这不应该是一个大问题。