用于CreateDocumentQuery的Linq样式查询<t>其中OrderBy

时间:2018-02-27 03:06:07

标签: c# azure-cosmosdb

我在互联网上找到了一个样本,用于使用SQL API从Azure Cosmos DB加载文档。 它似乎首先加载所有文档,然后是.Where和.OrderBy之后应用。是否有一种方法可以重写'GetItemsAsync'方法,以便下面的代码可以在不加载整个集合的情况下工作?

有没有办法以这种方式调用'GetItemsAsync'方法?

foreach(Member pMember in GetItemsAsync<Member>()
                              .Where(m=> m.Name == "Mike").OrderBy(m=> m.LastName))
{

}

将.AsEnumerable工作吗?

public static async Task<IEnumerable<T>> GetItemsAsync()
{
    IDocumentQuery<T> query = _documentClient.CreateDocumentQuery<T>(
    UriFactory.CreateDocumentCollectionUri(DatabaseId,CollectionId),
        new FeedOptions {  MaxItemCount = -1 }).AsDocumentQuery();

    List<T> results = new List<T>();
    while (query.HasMoreResults)
    {
        results.AddRange(await query.ExecuteNextAsync<T>());
    }

    return results;
}

还是我被迫像这样构造它:谓词作为方法中的参数?

public static async Task<IEnumerable<T>> GetItemsAsync(Expression<Func<T, bool>> predicate)
{
    IDocumentQuery<T> query = _documentClient.CreateDocumentQuery<T>(
    UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId),
        new FeedOptions {  MaxItemCount = -1 })
        .Where(predicate).AsDocumentQuery();

    List<T> results = new List<T>();
    while (query.HasMoreResults)
    {
        results.AddRange(await query.ExecuteNextAsync<T>());
    }

    return results;
}

1 个答案:

答案 0 :(得分:1)

我认为你必须使用第二种方法,即谓词作为参数的方法。

要在不加载数据库中的所有内容的情况下执行查询,您需要IQueryable而不是IEnumerable。要以异步方式执行,您需要IDocumentQuery,因为它被提到here

具体来说,要实现您想要实现的foreach形式,您可以执行类似以下示例的操作。

获取IQueryable

public static IQueryable<T> GetItemsQueryable<T>()
{
    IQueryable<T> query = client.CreateDocumentQuery<T>(
        collection.SelfLink,
        new FeedOptions { MaxItemCount = -1 })
        .AsQueryable<T>();

    return query;
}

然后像下面这样使用它:

foreach (var item in GetItemsQueryable<DeviceReading>()
    .Where(m => m.MetricType == "Temperature" && m.DeviceId == "XMS-0001")
    .OrderBy(m => m.MetricValue))
{
    Console.WriteLine(item.MetricValue);
}