【发布时间】:2016-09-07 14:52:07
【问题描述】:
我有大量的 MongoDB 项目 (> 10m)。
代码在 C#/.NET 中。
有时,我需要遍历所有文档以修剪数据、进行一些其他维护等。 此外,在某些情况下,我需要能够遍历所有文档,但只能获取每个文档的 ID。
我希望文档以 IEnumerable 的形式呈现,供用于处理列表等的代码使用。
我做了以下事情:
private static IAsyncCursor<MongoAlbum> GetCursor(Parameters...)
{
var F = MakeFilter(Parameters...);
var Cursor = Mongo.Driver.FindAsync(F).Result;
return Cursor;
}
internal static IEnumerable<string> IterateThroughAlbumIds(Parameters...)
{
using (var Cursor = GetCursor(Parameters...))
{
while (Cursor.MoveNextAsync().Result)
{
var Batch = Cursor.Current;
foreach (var Document in Batch) yield return Document._id;
}
}
}
internal static IEnumerable<MongoAlbum> IterateThroughAlbums(Parameters...)
{
using (var Cursor = GetCursor(Parameters...))
{
while (Cursor.MoveNextAsync().Result)
{
var Batch = Cursor.Current;
foreach (var Document in Batch) yield return Document;
}
}
}
现在我想知道两件事:
- 有没有更好的方法让异步枚举看起来像 .NET IEnumerable?
- 在枚举过程中,如何告诉驱动只返回一个文档的id?
【问题讨论】:
-
异步枚举在 .NET 中仍然是一个有问题的概念。当然有 Rx 和 Ix(Entity Framework async 建立在后者的概念之上),但两者都没有统一的支持。更有问题的是 async -> sync 逻辑转换(这就是你在这里得到的)。如果你必须有一个
IEnumerable<T>并同步调用它,并且你想用最少的编码工作来做到这一点,那么你正在做的是有点好的(虽然我'd 使用GetAwaiter().GetResult()进行阻塞而不是Result用于更清晰的异常传播)。
标签: c# .net mongodb-.net-driver