如何实现SkipWhile使用LINQ没有首先整个列表加载到内存中的SQL? [英] How to implement SkipWhile with Linq to Sql without first loading the whole list into memory?

查看:227
本文介绍了如何实现SkipWhile使用LINQ没有首先整个列表加载到内存中的SQL?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要按降序出版日期存储在数据库中的文章,然后用标识== 100的文章后,取前20条记录



这是我想使用LINQ做什么:

  IQueryable的<物品>文章= 
db.Articles
.OrderByDescending(A => a.PublicationDate)
.SkipWhile(A =>!a.Id = 100)
。取(20 );



不过,这会产生一个NotSupportedException异常,因为 SkipWhile Linq中不支​​持SQL(见这里< 。/ A>)



一个可能的解决方案是执行查询,然后应用 SkipWhile 使用LINQ to对象:

 的IEnumerable< ArticleDescriptor>文章= 
db.Articles
.OrderByDescending(A => a.PublicationDate)
.ToList()
.SkipWhile(A =>!a.Article.Id = 100)
。取(20);



但是,这意味着我需要先加载整个有序列表到内存中,然后取后20篇一个用标识== 100



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



在一般的多了,什么是SQL实现这一目标?


解决方案

如果,因为我是从列名的猜测, PublicationDate 不会改变,你可以在两个单独的查询做到这一点:




  • 树立 PublicationDate 的文章标识== 100

  • 从该日起20篇文章



是这样的:

  VAR thresholdDate = db.Articles.Single(A =>将.ID == 100).PublicationDate; 
变种文章=
db.Articles
。凡(A => a.PublicationDate< = thresholdDate)
.OrderByDescending(A => a.PublicationDate)
。取(20);



它甚至可能是LINQ到SQL可以翻译如下:

  VAR文章= 
db.Articles
。凡(A => a.PublicationDate
< = db.Articles。单(AA = GT; aa.Id == 100).PublicationDate)
.OrderByDescending(一个= GT; a.PublicationDate)
。取(20);



,但可能是因为它太复杂。试一试,看看。


I need to order the articles stored in a database by descending publication date and then take the first 20 records after the article with Id == 100.

This is what I would like to do with Linq:

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

However, this generates a NotSupportedException because SkipWhile is not supported in Linq to Sql (see here).

A possible solution is to execute the query and then apply SkipWhile using Linq to Object:

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

But this means I need to load the whole ordered list into memory first and then take 20 articles after the one with Id == 100.

Is there a way to avoid this huge memory consumption?

More in general, what is the best way to achieve this in SQL?

解决方案

If, as I'm guessing from the column name, PublicationDate doesn't change, you can do this in two separate queries:

  • Establish the PublicationDate of the Article with Id == 100
  • Retrieve the 20 articles from that date onwards

Something like:

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);

It might even be that LINQ to SQL can translate this:

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

but that may be too complex for it. Try it and see.

这篇关于如何实现SkipWhile使用LINQ没有首先整个列表加载到内存中的SQL?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆