我是否必须在查询中省略跳过调用

时间:2013-08-02 13:09:03

标签: c# linq

我有一张大桌子,我想要清除旧记录。记录有一个字段'FilePath'。这里的'clear'表示将'FilePath'标记为null。问题是因为该表有数百万条记录,一次更新是不可能的。它炸毁了记忆。所以我的策略是每次获取2000行并更新它们然后继续处理下一个块。

我的查询:

int pageNumber = 0;
int pageSize = 2000;
bool hasHitEnd = false;

while (!hasHitEnd)
{
var size = pageNumber * pageSize;
var query = cdrContext.Mytable.Where(c => c.FacilityID == facilityID && c.FilePath != null && c.TimeStationOffHook < oldDate)
    .OrderBy(c => c.TimeStationOffHook)
    .Skip(size)
    .Take(pageSize)
    .Select(c => new { c.FilePath, c.FileName })
    .ToList();
      var q = cdrContext.Mytable.Where(c => c.FacilityID == facilityID && c.FilePath != null && c.TimeStationOffHook < oldDate)
         .OrderBy(c => c.TimeStationOffHook)
         .Skip(size)
         .Take(pageSize)
         .ToList();
foreach (var y in q)
{
   y.FilePath = null;
}
cdrContext.SaveChanges();
if (query.Count() < pageSize)
{
    hasHitEnd = true;
}
pageNumber++;

我对代码不太自信。因为在更新数据后,FilePath为null。然后在下一次运行中,它可能不会指向右侧的块,因为我跳过一个块。

我是否需要删除跳过部分?

2 个答案:

答案 0 :(得分:1)

您不需要跳过记录,因为更新后的下一页将成为第一页(更新的项目将与您下次调用时的查询过滤器不匹配)。

// define query, but don't execute it
var query = cdrContext.Mytable.Where(c => c.FacilityID == facilityID && 
                                          c.FilePath != null && 
                                          c.TimeStationOffHook < oldDate)
                              .OrderBy(c => c.TimeStationOffHook)
                              .Take(pageSize);

List<Foo> itemsToUpdate = query.ToList(); // get first N items

while(itemsToUpdate.Any()) // all items updated
{
    // update items
    cdrContext.SaveChanges();
    itemsToUpdate = query.ToList(); // get first N items
}

答案 1 :(得分:1)

无需跳过记录,后续页面将成为您的第一页。你也不需要两次查询数据库我看到你使用查询和q这是没有必要的。只需使用q它将有助于提高性能。您可以删除以下代码

 if (query.Count() < pageSize)
 {
     hasHitEnd = true;
 }

如果q.Count()== 0,则将其替换为q中的记录数,然后您可以中断循环或设置hasHitEnd = true;