OData“列表中的 ID”询问

发布于 2024-12-10 02:59:04 字数 929 浏览 2 评论 0原文

我有一个 OData 服务,我试图按 ID 列表进行过滤; SQL 等效项类似于:

SELECT * FROM MyTable WHERE TableId IN (100, 200, 300, 400)

我尝试过滤的属性的类型为 Int32。我尝试了以下操作,这给了我一个错误“运算符'add'与操作数类型'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来查询服务。

有没有办法可以做我想做的事情,或者我是否坚持构建文本过滤器并使用 AddQueryOption,并迭代列表并手动添加“or media_id eq 100”子句?

I have an OData service where I'm trying to filter by a list of IDs; the SQL equivalent would be something like:

SELECT * FROM MyTable WHERE TableId IN (100, 200, 300, 400)

The property I'm trying to filter on is typed as an Int32. I've tried the following, which gives me an error "Operator 'add' incompatible with operand types 'Edm.String' and 'Edm.Int32'":

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

as well as

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

and

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

and

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

As you can see, currently I'm using LINQ to query the service.

Is there a way I can do what I'm trying to, or am I stuck constructing a text filter and using AddQueryOption, and iterating through the list and manually adding "or media_id eq 100" clauses?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

人事已非 2024-12-17 02:59:04

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

http://host/service/Products?$filter=Name in ('Milk', 'Cheese')

With OData 4.01, in statement is supported like this:

http://host/service/Products?$filter=Name in ('Milk', 'Cheese')
多孤肩上扛 2024-12-17 02:59:04

查看已接受的答案,以下所有内容均适用于 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;

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 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);

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

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

See accepted answer, everything below is for OData v < 4.01

try this one

 var ids = new [] { 100, 200, 300 } ;
 var res = from m in provider.Media 
           from id in ids 
           where m.media_id == id 
           select m;

there is a comprehensive description on msdn on querying DataServices.

another approach would be

var results = provider.Media
   .AddQueryOption("$filter", "media_id eq 100");

and since OData doesn't support IN statements you will come up with filter condition like this

.AddQueryOption("$filter", "(media_id eq 100) or (media_id eq 200 ) or ...");

which you can build using loop or linq Select and 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);

UPDATE: There is filter operation field=["a","b"] however it means something different.

UPDATE2: In OData V4 there is lambda expressions any and all, paired with array literal ["a", "b"] they might work as in but I was not able to come up with working example using v4 endpoint at OData.org

天荒地未老 2024-12-17 02:59:04

扩展 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),但它可以解决问题。

Expanding on vittore's answer (of which the second part is the correct answer), I've written something similar to the following for a demo project:

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();

It's not elegant, and you wouldn't want to use this for a large list of ids (> ~60), but it'll do the trick.

如此安好 2024-12-17 02:59:04

扩展MCattle的建议,如果我们需要更多50或60个id,那么建议进行2个或更多并行调用,并将它们添加到并发字典或类似的东西中,就像我们从服务器获取结果一样。虽然这增加了对服务器的调用次数,但由于我们正在慢慢迁移到云环境,我认为这不应该是一个大问题。

Expanding on MCattle suggestion if we need more 50 or 60 ids then its advisable to do in 2 or more parallel calls and add them to concurrent dictionary or something similar as we get results from server. Though this increases the number of calls to server but because we are slowly moving to cloud environment it shouldn't be a big problem in my opinion.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文