【问题标题】:How do I SKIP the already iterated rows but read the next rows that are not being iterated?如何跳过已经迭代的行但读取未迭代的下一行?
【发布时间】:2021-09-10 06:21:43
【问题描述】:

我正在尝试遍历一个集合,即,但它应该只根据分页值进行迭代。

看,我有这个:

var SkipCount= 0;
var TakeCount= 50;

var list= db.tblCollection.where(r => r.Id > 1).orderby(r=> r.Id).Take(Take).Skip(SkipCount);

var totalTableRecords= list.count(); // 200 records in my case
var counter= 0;

现在外部循环将一直运行,直到达到 totalTableRecords-1 的总值。 对于外循环的每次迭代的内循环,它应该只检查指定数量的记录。

for( ;counter < totalTableRecords; )
{
     foreach(var l in list)
     {
          //Do some coding here
          
          counter= counter + 1;
          
     }
          SkipCount= TakeCount;
          TakeCount= TakeCount+ 50;
          
}
          

我想要实现的是,在外循环的第 1 次运行中,内循环应根据修剪后的即1st 50 记录执行一些操作。然后,在第二次运行中,我们确实需要跳过第一次运行中已经执行的50 记录,并且应该是下一个50 记录。然后在第三个循环中,它将忽略1st2nd中已经读取的100记录,运行(50+50)和下一个50记录,直到外循环的计数器达到条件。

我试过这个,但它一直运行到极限,即200,而实际完成的工作只有4迭代。

我该如何解决这个问题?

【问题讨论】:

  • 如果要处理所有记录,则不需要记录总数,只需在每次外部迭代中获取 50 条下一条记录,直到没有更多记录可获取。 BR

标签: c# entity-framework linq linq-to-sql linq-to-entities


【解决方案1】:

我想也许您正在寻找类似下面的代码的东西。它将分 4 批迭代 200 多个项目。

public static IEnumerable<int> MyDataSource()
{
    Console.WriteLine("This will only be printed once");

    for (var i = 0; i < 200; i++)
    {
        yield return i;
    }
}

[Test]
public void SkipTest()
{
    var skipCount = 0;
    const int takeCount = 50;

    for (;;)
    {
        var currentList = MyDataSource().Skip(skipCount).Take(takeCount).ToArray();
        if (!currentList.Any())
        {
            return;                        
        }
        
        foreach (var currentVal in currentList)
        {
            Console.WriteLine(currentVal);
        }
        skipCount += takeCount;
    }
}

【讨论】:

    【解决方案2】:

    我感觉您发布的代码与您测试的代码不太一样。在内部循环中更改 SkipCountTakeCount(对于您迭代的每个项目)似乎是错误的。

    我会重写一点,但总的来说:保持TakeCount(页面大小)不变并增加SkipCount(页码):

    pageNum = 0; // Instead of SkipCount
    pageSize = 50; // Instead of TakeCount
    List<SomeType> page;
    
    do
    {
        page = db.tblCollection.Where(r => r.Id > 1)
            .OrderBy(r => r.Id)
            .Skip(pageNum * pageSize)
            .Take(pageSize)
            .ToList();
    
         foreach (var l in page)
         {
              //Do some coding here
         }
    
         pageNum++;
    } while (page.Count > 0);
    
    

    【讨论】:

    • 嗨,谢谢,但是 page.count > 0;它不会是无限的,因为我们没有做任何事情来计算计数吗?
    • 另外,我认为这件作品会迭代而不是停止
    • @afaaqadabookick 不,不应该。如果您有 200 条记录,那么当 pageNum 为 4 时,您将在列表中获得 0 项,因为您跳过了 4 * 50 = 200 并取了 50。但是你跳过的 200 之后没有记录,所以你实际上“取”了 0。
    • 啊啊啊啊好吧好吧。太好了,所以如果我有任意数量的行,比如说 500,它也适用吗?对吗?
    • @afaaqadabookick 是的。您可以在这里尝试一个示例:dotnetfiddle.net/i7EMcu 只需更改sourceCollection 的大小,看看会发生什么
    猜你喜欢
    • 2020-03-29
    • 1970-01-01
    • 1970-01-01
    • 2014-06-15
    • 2011-08-06
    • 2022-01-22
    • 1970-01-01
    • 1970-01-01
    • 2021-12-26
    相关资源
    最近更新 更多