C# DocumentDB LINQ匹配多个子对象

C# DocumentDB LINQ匹配多个子对象,c#,linq,azure-cosmosdb,C#,Linq,Azure Cosmosdb,我有一个简单的文件 { Name: "Foo", Tags: [ { Name: "Type", Value: "One" }, { Name: "Category", Value: "A" }, { Name: "Source", Value: "Example" }, ] } 我想进行LINQ查询,通过匹配多个标记,可以找到这些文档 i、 e.不是SQL查询,除非没有其他选项 e、 g 但如何扩展该方法以支持匹配多个子

我有一个简单的文件

{
    Name: "Foo",
    Tags: [
        { Name: "Type", Value: "One" },
        { Name: "Category", Value: "A" },
        { Name: "Source", Value: "Example" },
    ]
}
我想进行LINQ查询,通过匹配多个
标记
,可以找到这些文档

i、 e.不是SQL查询,除非没有其他选项

e、 g

但如何扩展该方法以支持匹配多个子对象还不清楚

我发现有一个名为ARRAY_CONTAINS的函数可以使用:

但我遇到的所有示例都使用SQL查询

这表明LINQ支持将在2015年“很快”推出,但从未跟进,所以我认为没有添加

我没有在LINQ中看到任何关于
ARRAY\u包含的
的文档,只有在

我尝试了以下SQL查询,以查看它是否符合我的要求,但未返回任何结果:

SELECT  Document
FROM    Document
WHERE   ARRAY_CONTAINS(Document.Tags, { Name: "Type", Value: "One" })
AND     ARRAY_CONTAINS(Document.Tags, { Name: "Category", Value: "A" })
根据
ARRAY\u CONTAINS
仅适用于原语数组,而不适用于对象。因此,它似乎不适合我想要实现的目标。

似乎对这个答案的评论是错误的,我的查询中有语法错误。我需要在属性名称周围添加双引号

运行此查询确实返回了我想要的结果:

SELECT  Document
FROM    Document
WHERE   ARRAY_CONTAINS(Document.Tags, { "Name": "Type", "Value": "One" })
AND     ARRAY_CONTAINS(Document.Tags, { "Name": "Category", "Value": "A" })

因此,
ARRAY\u CONTAINS
似乎实现了我想要的功能,因此我正在寻找如何通过LINQ语法使用它

在LINQ查询中使用
.Contains
将生成使用
数组\u Contains
的SQL

因此:

您可以链接
。其中
调用以创建
谓词链

因此:


如果需要使用
链接谓词,则需要一些表达式谓词生成器库。

这并不难。您需要类标记来实现比较多个标记的IComparable。@jdweng和DocumentDB LINQ提供程序了解如何将该自定义IComparable转换为正确的SQL查询?支持一些
包含
,因此我想知道
在哪里(d=>d.tags.Contains(singleTagToMatch))
起作用?因为如果这样做了,我们最终可以动态地构建与您在SQL查询中使用的类似的
&
谓词表达式。@IvanStoev这是一个非常好的想法,谢谢!我将做一些调查,看看.Contains会产生什么。@IvanStoev调用query.ToString将查询转换为它将发送到后端的SQL。看看SQL
,其中(d=>d.Tags.Contains(singleTagToMatch))生成
其中数组包含(根[“标记”],{“名称”:“类型”,“值”:“一”})
这是完美的!我现在正在研究动态构建LINQ谓词。谢谢你的回答,这为我解决了这个问题。我希望您不介意,我已经扩展了答案,提供了更多的细节和示例。欢迎您,很高兴它有帮助:)当然(事实上,谢谢您,解释不是我最好的优势:)那么,如果您只希望其中一个元素(名称或值)匹配,这是如何工作的呢?我尝试在Tag类上重写Equals,并在其中一个元素/属性上使用EqualityComparer重写Equals,但这不起作用。@caren您尝试的内容仅在LINQ to对象中起作用。我现在无法测试,但您可以尝试组合
Select
+
Contains
,例如
query.Where(s=>s.Tags.Select(t=>t.Name).Contains(tagToMatch.Name))我收到一个错误,表示不支持Select方法。我尝试了一点SelectMany,但后来得到了重复的结果。
SELECT  Document
FROM    Document
WHERE   ARRAY_CONTAINS(Document.Tags, { Name: "Type", Value: "One" })
AND     ARRAY_CONTAINS(Document.Tags, { Name: "Category", Value: "A" })
SELECT  Document
FROM    Document
WHERE   ARRAY_CONTAINS(Document.Tags, { "Name": "Type", "Value": "One" })
AND     ARRAY_CONTAINS(Document.Tags, { "Name": "Category", "Value": "A" })
var tagsToMatch = new List<Tag>()
{
    new Tag("Type", "One"),
    new Tag("Category", "A")
};

var singleTagToMatch = tagsToMatch.First();

var query = client
    .CreateDocumentQuery<T>(documentCollectionUri)
    .Where(d => d.Tags.Contains(singleTagToMatch));
SELECT * FROM root WHERE ARRAY_CONTAINS(root["Tags"], {"Name":"Type","Value":"One"})
var query = client.CreateDocumentQuery<T>(documentCollectionUri)

foreach (var tagToMatch in tagsToMatch)
{
    query = query.Where(s => s.Tags.Contains(tagToMatch));
}
SELECT * FROM root WHERE ARRAY_CONTAINS(root["Tags"], {"Name":"Type","Value":"One"}) AND ARRAY_CONTAINS(root["Tags"], {"Name":"Category","Value":"A"})