Ale*_*AIT 6 .net c# azure azure-cosmosdb
我们确实不得不从 Linq-Queries 转移到我们的 DocumentDB/CosmosDB。
原因主要是两个用例:
像这样连接(示例有点奇怪)。
SqlQuerySpec spec = new SqlQuerySpec(@"
SELECT value(n)
FROM books b
join p in b.author.parents
where b.isbn = @isbnId
AND lower(p.address.street) = @parentStreet
");
Run Code Online (Sandbox Code Playgroud)所以我们的查询看起来像这样:
IQueryable<Book> queryable = client.CreateDocumentQuery<Book>(
collectionSelfLink,
new SqlQuerySpec
{
QueryText = "SELECT * FROM books b WHERE (b.Author.Name = @name)",
Parameters = new SqlParameterCollection()
{
new SqlParameter("@name", "Herman Melville")
}
});
Run Code Online (Sandbox Code Playgroud)
但是,随着我们的需求变得越来越复杂,我们需要根据给定的参数使查询看起来不同。我们还有“in”查询,需要我们添加多个参数。
所以现在我们的代码看起来像这样......
var sqlParameterCollection = new SqlParameterCollection();
for (int i = 0; i < ids.Length; i++)
{
var key = "@myid" + i;
sqlParameterCollection.Add(new SqlParameter(key, ids[i]));
}
[...]
var query = $@"
{select}
FROM collection m
WHERE m.myid IN ({string.Join(",", sqlParameterCollection.Select(p => p.Name))})
";
Run Code Online (Sandbox Code Playgroud)
接下来,需要根据某些参数使用额外的过滤器扩展 where 子句
由于情况越来越糟:是否有可用的查询构建器?我正在考虑一个流畅的 api,它在理想情况下还可以包含 SqlParameters,而不仅仅是查询文本。
伪代码:
queryBuilder
.from("m")
.select("field1")
.select("field2")
.where("myid", Operators.In, ...)
.And(...
Run Code Online (Sandbox Code Playgroud)
我们最终不需要构建查询生成器。我们低估了使用的力量SelectMany
。
我们最终做了这样的事情
var query = client.CreateDocumentQuery<Book>(collectionSelfLink)
// Join with select many
.SelectMany(book => book.author.parents
// Stay within the original SelectMany to do the filtering
.Where(parents => parents.address.street == "parentstreet")
// Stay within the original SelectMany to return the root node
// .Select(x => book)
// Or do a partial select
// .Select(x => new {book.title, book.author.name})
)
.AsDocumentQuery();
Run Code Online (Sandbox Code Playgroud)
这个答案和其他例子有很大帮助:
private static void QueryWithTwoJoins(string collectionLink)
{
// SQL
var familiesChildrenAndPets = client.CreateDocumentQuery<dynamic>(collectionLink,
"SELECT f.id as family, c.FirstName AS child, p.GivenName AS pet " +
"FROM Families f " +
"JOIN c IN f.Children " +
"JOIN p IN c.Pets ");
foreach (var item in familiesChildrenAndPets)
{
Console.WriteLine(item);
}
// LINQ
familiesChildrenAndPets = client.CreateDocumentQuery<Family>(collectionLink)
.SelectMany(family => family.Children
.SelectMany(child => child.Pets
.Select(pet => new
{
family = family.Id,
child = child.FirstName,
pet = pet.GivenName
}
)));
foreach (var item in familiesChildrenAndPets)
{
Console.WriteLine(item);
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4258 次 |
最近记录: |