首页 > 解决方案 > 用 TAKE 查询并检查它是否为空

问题描述

我正在尝试从 Cosmos DB 获取信息,并且我想获取一定数量的行或所有行。例如,用户可以输入 100,他将只获得 100 行,如果他不输入任何内容,他将获得所有行。

在我使用 .Take() 获得信息之前,例如:.Take(amount),但如果金额为空,我将失败。

和:

.Take(amount)

我想要这样的东西:

.TakeIf(amount != null, amount);

我知道上面的行是错误的,但这就是想法。

下面的行是完整的查询。

var resultDTO = this.client.CreateDocumentQuery<DTO>(
     UriFactory.CreateDocumentCollectionUri(idDatabase, idCollection), queryOptions)
     .WhereIf(sourceId != null, x => x.sourceId == sourceId)
     .Take(amount)
     .AsEnumerable()
     .ToList();

如何检查金额是否为空?

标签: c#linqazure-cosmosdb

解决方案


这更感谢仅配置表达式。CosmosDB 默认只返回分页结果。如果您使用同步AsEnumerable().ToList()方法,您的代码将以同步方式遍历所有页面。这将导致糟糕的表现。你想做的是迭代和收集。可悲的是,没有花哨的方法来解决这个问题。

遗憾的是,您无法将所有必要的代码封装在一个TakeIf调用中,因为在查询期间还需要执行更多操作。

这是一个代码示例。

var amount = 100;

var queryOptions = new RequestOptions {
    MaxItemCount = 100
};

var queryable = this.client.CreateDocumentQuery<DTO>(
     UriFactory.CreateDocumentCollectionUri(idDatabase, idCollection), queryOptions)
     .WhereIf(sourceId != null, x => x.sourceId == sourceId);


if(amount != null && amount > 0){
    queryable.Take(amount);
}

var documentQuery = queryable.AsDocumentQuery();

var results = new List<DTO>();
while (query.HasMoreResults)
{
    if (amount != null && amount > 0 && results.Count == amount)
        break;

    var items = await query.ExecuteNextAsync<DTO>(cancellationToken);

    foreach (var item in items)
    {
        results.Add(item);

        if (amount != null && amount > 0 && results.Count == amount)
            break;
    }
}
return results;

在此示例中,我假设您只想Take在金额不为空且大于 0 时添加调用。如果不是这种情况,则删除> 0支票。

有关此检查Cosmonaut 的源代码的更详细示例,请单击此处


推荐阅读