DocumentDB LINQ 匹配多个子对象
DocumentDB LINQ match multiple child objects
我有一个简单的文档。
{
Name: "Foo",
Tags: [
{ Name: "Type", Value: "One" },
{ Name: "Category", Value: "A" },
{ Name: "Source", Value: "Example" },
]
}
我想创建一个 LINQ 查询,可以通过匹配多个 Tags
.
来找到这些文档
即不是 SQL 查询,除非没有其他选择。
例如
var tagsToMatch = new List<Tag>()
{
new Tag("Type", "One"),
new Tag("Category", "A")
};
var query = client
.CreateDocumentQuery<T>(documentCollectionUri)
.Where(d => tagsToMatch.All(tagToMatch => d.Tags.Any(tag => tag == tagToMatch)));
这给我错误 Method 'All' is not supported.
。
我找到了匹配子对象上的单个 属性 的示例:
var singleTagToMatch = tagsToMatch.First();
var query = client
.CreateDocumentQuery<T>(documentCollectionUri)
.SelectMany
(
d => d.Tags
.Where(t => t.Name == singleTagToMatch.Name && t.Value == singleTagToMatch.Value)
.Select(t => d)
);
但如何扩展该方法以支持匹配多个子对象并不明显。
我发现有一个叫做ARRAY_CONTAINS的函数可以使用:
但我遇到的所有示例都使用 SQL 查询。
这 thread 表明 LINQ 支持在 2015 年 "coming soon",但从未跟进,所以我认为它没有被添加。
我没有在 LINQ 中找到 ARRAY_CONTAINS
的任何文档,仅在 SQL.
中
我尝试了以下 SQL 查询以查看它是否符合我的要求,但没有 return 任何结果:
SELECT Document
FROM Document
WHERE ARRAY_CONTAINS(Document.Tags, { Name: "Type", Value: "One" })
AND ARRAY_CONTAINS(Document.Tags, { Name: "Category", Value: "A" })
根据 ,ARRAY_CONTAINS
仅适用于基元数组,不适用于对象。所以它似乎不适合我想要实现的目标。
似乎对该答案的评论是错误的,而且我的查询中存在语法错误。我需要在 属性 名称周围添加双引号。
运行 这个查询 return 我想要的结果:
SELECT Document
FROM Document
WHERE ARRAY_CONTAINS(Document.Tags, { "Name": "Type", "Value": "One" })
AND ARRAY_CONTAINS(Document.Tags, { "Name": "Category", "Value": "A" })
所以 ARRAY_CONTAINS
似乎确实实现了我想要的,所以我正在寻找如何通过 LINQ 语法使用它。
在 LINQ 查询中使用 .Contains
将生成使用 ARRAY_CONTAINS
.
的 SQL
所以:
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"})
您可以链接 .Where
个调用来创建一个 AND
谓词链。
所以:
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"})
如果您需要使用 OR
链接谓词,那么您将需要一些表达式谓词生成器库。
我有一个简单的文档。
{
Name: "Foo",
Tags: [
{ Name: "Type", Value: "One" },
{ Name: "Category", Value: "A" },
{ Name: "Source", Value: "Example" },
]
}
我想创建一个 LINQ 查询,可以通过匹配多个 Tags
.
即不是 SQL 查询,除非没有其他选择。
例如
var tagsToMatch = new List<Tag>()
{
new Tag("Type", "One"),
new Tag("Category", "A")
};
var query = client
.CreateDocumentQuery<T>(documentCollectionUri)
.Where(d => tagsToMatch.All(tagToMatch => d.Tags.Any(tag => tag == tagToMatch)));
这给我错误 Method 'All' is not supported.
。
我找到了匹配子对象上的单个 属性 的示例:
var singleTagToMatch = tagsToMatch.First();
var query = client
.CreateDocumentQuery<T>(documentCollectionUri)
.SelectMany
(
d => d.Tags
.Where(t => t.Name == singleTagToMatch.Name && t.Value == singleTagToMatch.Value)
.Select(t => d)
);
但如何扩展该方法以支持匹配多个子对象并不明显。
我发现有一个叫做ARRAY_CONTAINS的函数可以使用:
但我遇到的所有示例都使用 SQL 查询。
这 thread 表明 LINQ 支持在 2015 年 "coming soon",但从未跟进,所以我认为它没有被添加。
我没有在 LINQ 中找到 ARRAY_CONTAINS
的任何文档,仅在 SQL.
我尝试了以下 SQL 查询以查看它是否符合我的要求,但没有 return 任何结果:
SELECT Document
FROM Document
WHERE ARRAY_CONTAINS(Document.Tags, { Name: "Type", Value: "One" })
AND ARRAY_CONTAINS(Document.Tags, { Name: "Category", Value: "A" })
根据 ARRAY_CONTAINS
仅适用于基元数组,不适用于对象。所以它似乎不适合我想要实现的目标。
似乎对该答案的评论是错误的,而且我的查询中存在语法错误。我需要在 属性 名称周围添加双引号。
运行 这个查询 return 我想要的结果:
SELECT Document
FROM Document
WHERE ARRAY_CONTAINS(Document.Tags, { "Name": "Type", "Value": "One" })
AND ARRAY_CONTAINS(Document.Tags, { "Name": "Category", "Value": "A" })
所以 ARRAY_CONTAINS
似乎确实实现了我想要的,所以我正在寻找如何通过 LINQ 语法使用它。
在 LINQ 查询中使用 .Contains
将生成使用 ARRAY_CONTAINS
.
所以:
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"})
您可以链接 .Where
个调用来创建一个 AND
谓词链。
所以:
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"})
如果您需要使用 OR
链接谓词,那么您将需要一些表达式谓词生成器库。