OData"列表中的ID"查询

tec*_*ile 51 linq collections filter odata

我有一个OData服务,我试图通过ID列表过滤; SQL等价物将是这样的:

SELECT * FROM MyTable WHERE TableId IN (100, 200, 300, 400)
Run Code Online (Sandbox Code Playgroud)

我想要过滤的属性是作为Int32键入的.我尝试了以下内容,它给出了一个错误"运算符'添加'与操作数类型'Edm.String'和'Edm.Int32'不兼容":

string ids = ",100,200,300,400,";
from m in provider.Media where ids.Contains("," + t.media_id + ",")
Run Code Online (Sandbox Code Playgroud)

以及

string ids = ",100,200,300,400,";
from m in provider.Media where ids.Contains("," + t.media_id.ToString() + ",")
Run Code Online (Sandbox Code Playgroud)

string ids = ",100,200,300,400,";
from m in provider.Media where ids.Contains("," + Convert.ToString(t.media_id) + ",")
Run Code Online (Sandbox Code Playgroud)

string ids = ",100,200,300,400,";
from m in provider.Media where ids.Contains(string.Concat(",", t.media_id, ","))
Run Code Online (Sandbox Code Playgroud)

如您所见,目前我正在使用LINQ来查询服务.

有没有办法,我可以做我正在尝试的,或者我是不是构建文本过滤器和使用AddQueryOption,并迭代列表并手动添加"或media_id eq 100"条款?

vit*_*ore 35

请参阅已接受的答案,以下所有内容均适用于OData v <4.01

试试这个

 var ids = new [] { 100, 200, 300 } ;
 var res = from m in provider.Media 
           from id in ids 
           where m.media_id == id 
           select m;
Run Code Online (Sandbox Code Playgroud)

msdn在查询DataServices时有一个全面的描述.

另一种方法是

var results = provider.Media
   .AddQueryOption("$filter", "media_id eq 100");
Run Code Online (Sandbox Code Playgroud)

因为OData不支持IN语句,所以你会得到像这样的过滤条件

.AddQueryOption("$filter", "(media_id eq 100) or (media_id eq 200 ) or ...");
Run Code Online (Sandbox Code Playgroud)

您可以使用构建环或LINQ Selectstring.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);
Run Code Online (Sandbox Code Playgroud)

更新:有过滤操作,field=["a","b"]但它意味着不同的东西.

UPDATE2:在OData V4中有lambda表达式,any并且all与数组文字配对["a", "b"]它们可能起作用in但我无法在OData.org上使用v4端点提出工作示例

  • "......因为OData不支持`IN`语句......",这是我一直在寻找的关键 (2认同)

mar*_*oss 26

使用OData 4.01,in语句支持如下:

http://host/service/Products?$filter=Name in ('Milk', 'Cheese')
Run Code Online (Sandbox Code Playgroud)

  • 它只花了7年时间.:D谢谢! (15认同)

MCa*_*tle 13

扩展了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();
Run Code Online (Sandbox Code Playgroud)

它并不优雅,你不想将它用于大量的id(> ~60),但它会做到这一点.