MongoDB:处理游标

时间:2011-05-18 22:56:45

标签: c# mongodb mongodb-.net-driver

摘自C#Driver:

It is important that a cursor cleanly release any resources it holds. The key to guaranteeing this is to make sure the Dispose method of the enumerator is called. The foreach statement and the LINQ extension methods all guarantee that Dispose will be called. Only if you enumerate the cursor manually are you responsible for calling Dispose.

通过调用

创建游标“res”
var res = images.Find(query).SetFields(fb).SetLimit(1);

没有Dispose方法。我该如何处理它?<​​/ p>

2 个答案:

答案 0 :(得分:9)

查询返回MongoCursor<BsonDocument>,但未实现IDisposable,因此您无法在使用块中使用它。

重要的一点是光标的枚举器必须处理,而不是光标本身,所以如果你直接使用光标的IEnumerator<BsonDocument>迭代光标那么你需要处理它,像这样:

using (var iterator = images.Find(query).SetLimit(1).GetEnumerator())
{
    while (iterator.MoveNext())
    {
        var bsonDoc = iterator.Current;
        // do something with bsonDoc
    }
}

但是,您可能永远不会这样做并使用foreach循环代替。当枚举器实现IDisposable时,就像使用foreach 保证一样,无论循环如何终止,都将调用其Dispose()方法。

因此,在没有任何明确处理的情况下循环这样是安全的:

foreach (var bsonDocs in images.Find(query).SetLimit(1))
{
    // do something with bsonDoc                
}

正在使用Enumerable.ToList<T>评估查询,它使用幕后的foreach循环:

var list = images.Find(query).SetLimit(1).ToList();

答案 1 :(得分:3)

您不需要在光标上调用Dispose(事实上MongoCursor甚至没有Dispose方法)。您需要做的是在MongoCursor的GetEnumerator方法返回的枚举器上调用Dispose。当您使用foreach语句或迭代IEnumerable的任何LINQ方法时,会自动发生这种情况。因此,除非您自己调用GetEnumerator,否则您不必担心调用Dispose。