如何在不首先将整个列表加载到内存中的情况下使用Linq to Sql实现SkipWhile?

我需要通过降序发布日期来订购存储在数据库中的文章,然后在Id == 100的文章之后获取前20条记录。

这就是我想对Linq做的事情:

 IQueryable
articles = db.Articles .OrderByDescending(a => a.PublicationDate) .SkipWhile(a => a.Id != 100) .Take(20);

但是,这会生成NotSupportedException,因为Linq to Sql不支持SkipWhile (请参阅此处 )。

一种可能的解决方案是执行查询,然后使用Linq将SkipWhile应用于Object:

 IEnumerable articles = db.Articles .OrderByDescending(a => a.PublicationDate) .ToList() .SkipWhile(a => a.Article.Id != 100) .Take(20); 

但这意味着我需要首先将整个有序列表加载到内存中,然后在Id == 100之后再加载20篇文章。

有没有办法避免这种巨大的内存消耗?

更一般地说,在SQL中实现这一目标的最佳方法是什么?

如果,正如我从列名称中猜测的那样, PublicationDate不会更改,则可以在两个单独的查询中执行此操作:

  • 使用Id == 100建立文章的PublicationDate
  • 从那个日期开始检索20篇文章

就像是:

 var thresholdDate = db.Articles.Single(a => a.Id == 100).PublicationDate; var articles = db.Articles .Where(a => a.PublicationDate <= thresholdDate) .OrderByDescending(a => a.PublicationDate) .Take(20); 

它甚至可能是LINQ to SQL可以翻译这个:

 var articles = db.Articles .Where(a => a.PublicationDate <= db.Articles.Single(aa => aa.Id == 100).PublicationDate) .OrderByDescending(a => a.PublicationDate) .Take(20); 

但这可能太复杂了。 试试看吧。

你可以这样试试

 var articles = db.Articles .Where(a => a.PublicationDate < db.Articles .Where(aa => aa.Id==100) .Select(aa => aa.PublicationDate) .SingleOrDefault()) .OrderByDescending(a => a.PublicationDate) .Take(20); 

是不是只添加一个where语句的解决方案?

 IQueryable
articles = db.Articles.Where(a => a.id != 100).OrderByDescending(a => a.PublicationDate).Take(20);