如何在不首先将整个列表加载到内存的情况下,用Linq实现SkipWhile到Sql
本文关键字:情况下 内存 Linq Sql SkipWhile 实现 加载 列表 | 更新日期: 2023-09-27 18:23:56
我需要按发布日期降序排列存储在数据库中的文章,然后用Id == 100
获取文章后面的前20条记录。
这就是我想用Linq:做的事情
IQueryable<Article> articles =
db.Articles
.OrderByDescending(a => a.PublicationDate)
.SkipWhile(a => a.Id != 100)
.Take(20);
但是,这会生成NotSupportedException,因为在Linq-to-Sql中不支持SkipWhile
(请参阅此处)。
一个可能的解决方案是执行查询,然后使用Linq将SkipWhile
应用于对象:
IEnumerable<ArticleDescriptor> articles =
db.Articles
.OrderByDescending(a => a.PublicationDate)
.ToList()
.SkipWhile(a => a.Article.Id != 100)
.Take(20);
但这意味着我需要先将整个有序列表加载到内存中,然后在使用Id == 100
的列表之后再获取20篇文章。
有没有办法避免这种巨大的内存消耗?
更一般地说,在SQL中实现这一点的最佳方法是什么?
根据列名,如果PublicationDate
没有更改,您可以在两个单独的查询中执行此操作:
- 用
Id == 100
建立Article
的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到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<Article> articles = db.Articles.Where(a => a.id != 100).OrderByDescending(a => a.PublicationDate).Take(20);