C# 如何在游标上运行最终迭代的代码
我有一个存储库函数GetDocs(),它返回一个MongoDB游标 在调用GetDocs的地方,我迭代光标,每迭代五次,我就调用SetLastId() 问题:如何确定何时处理光标的最后一个元素,以便在退出循环之前调用SetLastId()C# 如何在游标上运行最终迭代的代码,c#,mongodb,mongodb-.net-driver,database-cursor,C#,Mongodb,Mongodb .net Driver,Database Cursor,我有一个存储库函数GetDocs(),它返回一个MongoDB游标 在调用GetDocs的地方,我迭代光标,每迭代五次,我就调用SetLastId() 问题:如何确定何时处理光标的最后一个元素,以便在退出循环之前调用SetLastId() public async Task GetDocs(string id, Func<Model, Task> processor) { var filter = Builders<Model>.F
public async Task GetDocs(string id, Func<Model, Task> processor)
{
var filter = Builders<Model>.Filter;
var sort = Builders<Model>.Sort;
using (var cursor = await Coll.Find(filter.Eq(f => f.id, id)).ToCursorAsync())
{
foreach (var doc in cursor.Current)
{
await processor(doc);
}
}
}
像这样的怎么样?基本上,循环将把上一个文档存储在内存中,并在下一次迭代中处理它。这样,一旦退出循环,它就有“最后一个文档”要处理,并可以将其标记为处理器
public async Task GetDocs(string id, Func<Model, bool, Task> processor)
{
var filter = Builders<Model>.Filter;
var sort = Builders<Model>.Sort;
using (var cursor = await Coll.Find(filter.Eq(f => f.id, id)).ToCursorAsync())
{
Model previousDoc = null;
foreach (var doc in cursor.Current)
{
if (previousDoc != null)
{
await processor(previousDoc, false);
}
previousDoc = doc;
}
if (previousDoc != null)
{
await processor(previousDoc, true);
}
}
}
public异步任务GetDocs(字符串id,Func处理器)
{
var-filter=Builders.filter;
var sort=Builders.sort;
使用(var cursor=await Coll.Find(filter.Eq(f=>f.id,id)).ToCursorAsync())
{
模型previousDoc=null;
foreach(游标中的var doc.Current)
{
如果(previousDoc!=null)
{
等待处理器(previousDoc,false);
}
previousDoc=doc;
}
如果(previousDoc!=null)
{
等待处理器(previousDoc,true);
}
}
}
您还可以将其包装成一个可重用的方法,该方法可用于任何IEnumerable(我在这里使用过,但如果您不能使用它们,您可以创建自己的类型):
公共静态IEnumerable映射(IEnumerable项)
{
T prevModel=默认值(T);
bool isFirst=true;
foreach(项目中的var模型)
{
如果(!isFirst)
{
收益率回报(prevModel,false);
}
其他的
{
isFirst=false;
}
模型=模型;
}
如果(!isFirst)
{
收益率回报率(prevModel,true);
}
}
公共异步任务GetDocs(字符串id,Func处理器)
{
var-filter=Builders.filter;
var sort=Builders.sort;
使用(var cursor=await Coll.Find(filter.Eq(f=>f.id,id)).ToCursorAsync())
{
foreach(映射中的var docWrapper(cursor.Current))
{
等待处理器(docWrapper.Model、docWrapper.IsLast);
}
}
}
我假设您希望以某种方式将“ObjectId lastId=ObjectId.Empty;”置于“repo.GetDocs”循环之外。我有理由只考虑将“doc.Id”分配给循环外的变量,但如果我不必这样做,我的代码会干净得多。我一直在考虑如何在错误的代码段中这样做。这正是我需要的。谢谢
public async Task GetDocs(string id, Func<Model, bool, Task> processor)
{
var filter = Builders<Model>.Filter;
var sort = Builders<Model>.Sort;
using (var cursor = await Coll.Find(filter.Eq(f => f.id, id)).ToCursorAsync())
{
Model previousDoc = null;
foreach (var doc in cursor.Current)
{
if (previousDoc != null)
{
await processor(previousDoc, false);
}
previousDoc = doc;
}
if (previousDoc != null)
{
await processor(previousDoc, true);
}
}
}
public static IEnumerable<(T Model, bool IsLast)> Map<T>(IEnumerable<T> items)
{
T prevModel = default(T);
bool isFirst = true;
foreach (var model in items)
{
if (!isFirst)
{
yield return (prevModel, false);
}
else
{
isFirst = false;
}
prevModel = model;
}
if (!isFirst)
{
yield return (prevModel, true);
}
}
public async Task GetDocs(string id, Func<Model, bool, Task> processor)
{
var filter = Builders<Model>.Filter;
var sort = Builders<Model>.Sort;
using (var cursor = await Coll.Find(filter.Eq(f => f.id, id)).ToCursorAsync())
{
foreach (var docWrapper in Map(cursor.Current))
{
await processor(docWrapper.Model, docWrapper.IsLast);
}
}
}