[英]How to query Cosmos DB if array property contains any item from a given list?
如果你有一個像這樣的實體 class 存儲在你的 cosmos 數據庫中
public class SomeItem
{
public Guid Id { get; set; }
public IReadOnlyList<string> AffectedUsers { get; set; }
}
在您的代碼中,您會收到一個用戶列表,並且您必須查詢列出其中任何一個的所有項目:
var cosmosClient = new CosmosClient("https://test.local/", "Tm9LZXk=");
var container = cosmosClient.GetContainer("123", "456");
// A list of users where we like to get all items, where any of them is listed in affected users.
var someUsers = Enumerable.Range(1, 5).Select(i => $"User {i}").ToList();
// The query that should check if any user of the above list is within affectedUsers
var query = container.GetItemLinqQueryable<SomeItem>()
// How to check for any element in someUsers is within affectedUsers dynamically?
.Where(item => item.AffectedUsers.Contains(someUsers[0]));
var definition = query.ToQueryDefinition();
var text = definition.QueryText;
Console.WriteLine(text);
要解決這個問題,需要一些基於LinqKit的神奇代碼:
public static class QueryableExtensions
{
public static IQueryable<T> WhereAny<T, U>(this IQueryable<T> source, IEnumerable<U> items, Expression<Func<T, U, bool>> expression)
{
var predicate = PredicateBuilder.New<T>();
foreach (var item in items)
{
Expression<Func<T, bool>> comparison = p => expression.Invoke(p, item);
predicate = predicate.Or(comparison.Expand());
}
return source.Where(predicate);
}
}
在您的工具帶中使用此方法,您可以按如下方式編寫查詢:
var query = container.GetItemLinqQueryable<SomeItem>()
.WhereAny(someUsers, (item, user) => item.AffectedUsers.Contains(user));
生成的 cosmos 查詢將是:
SELECT VALUE root FROM root WHERE ((((ARRAY_CONTAINS(root["AffectedUsers"], "User 1")
OR ARRAY_CONTAINS(root["AffectedUsers"], "User 2"))
OR ARRAY_CONTAINS(root["AffectedUsers"], "User 3"))
OR ARRAY_CONTAINS(root["AffectedUsers"], "User 4"))
OR ARRAY_CONTAINS(root["AffectedUsers"], "User 5"))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.