如何将CosmosDBFeedIterator结果转换为IAsyncEnumerable或IEnumerable?
c#
将 CosmosDb FeedIterator 中的数据以一种简单的可重用方式转换为 IEnumerable 而不必到处编写循环和迭代,这有点棘手。
在微软官方的例子,因为我喜欢它看起来像这里面是不是整齐:
using (FeedIterator setIterator = container.GetItemLinqQueryable<Book>()
.Where(b => b.Title == "War and Peace")
.ToFeedIterator())
{
//Asynchronous query execution
while (setIterator.HasMoreResults)
{
foreach(var item in await setIterator.ReadNextAsync())
{
Console.WriteLine(item.Price);
}
}
}
我想要一个可重复使用的oneliner,但没有找到,所以我写了一个。
特别是当它用于 .NET API 时,所以我编写了一个扩展方法将 FeedIterator 转换为 IAsyncEnumerable,您可以使用
(在 C# 8 中,您可以从 API 返回 IAsyncEnumerable,但如果您需要像我一样与 netstandard2.0 兼容,您可以将 IAsyncEnumerable 转换为常规 IEnumerable)
回答
我是这样解决的:
扩展方法:
public static class CosmosDbExtensions
{
/// <summary>
/// Convert a feed iterator to IAsyncEnumerable
/// </summary>
/// <typeparam name="TModel"></typeparam>
/// <param name="setIterator"></param>
/// <returns></returns>
public static async IAsyncEnumerable<TModel> ToAsyncEnumerable<TModel>(this FeedIterator<TModel> setIterator)
{
while (setIterator.HasMoreResults)
foreach (var item in await setIterator.ReadNextAsync())
{
yield return item;
}
}
}
返回 IAsyncEnumerable:
public virtual IAsyncEnumerable<TModel> Query()
{
Container container = GetContainer(); // Your code to get container
return container.GetItemLinqQueryable<TModel>().ToFeedIterator().ToAsyncEnumerable();
}
返回 IEnumerable:
public virtual async Task<IEnumerable<TModel>> Query()
{
Container container = GetContainer(); // Your code to get container
using (var feedIterator = container.GetItemLinqQueryable<TModel>().ToFeedIterator())
{
return await feedIterator.ToAsyncEnumerable().ToListAsync();
}
}
(更多关于 .ToListAsync() 来自 System.Linq.Async 包在这个线程中)
THE END
二维码