小编典典

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

sql

我需要按发布日期降序对存储在数据库中的文章进行排序,然后使用来记录文章之后的前20条记录Id == 100

这就是我要对Linq进行的操作:

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

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

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

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

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

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

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


阅读 155

收藏
2021-04-07

共1个答案

小编典典

根据我在列名中的猜测,PublicationDate如果没有更改,则可以在两个单独的查询中执行此操作:

  • 建立PublicationDateArticleId == 100
  • 从该日期起检索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);

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

2021-04-07