如何在不首先将整个列表加载到内存中的情况下使用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);