实体框架 - SkipWhile

3

我有一些按日期降序排列的行:

var query = this.DbContext.Items.OrderByDescending(g => g.UpdatedAt);

0 Dog       2016-03-08
9 Cat       2016-03-07
2 Elephant  2016-03-06
8 Apple     2016-03-05
3 Banana    2016-03-04
7 Juice     2016-03-03
4 Potato    2016-03-02
5 Cafee     2016-03-01

第一个查询返回有序元素的有限数量(例如4个):

var result = query.Take(4).ToList();

0 Dog       2016-03-08
9 Cat       2016-03-07
2 Elephant  2016-03-06
8 Apple     2016-03-05

下一个查询应该返回从ID 3开始的4个有序元素:
var result = query.ToList()
             .SkipWhile(g => g.Id != startFrom.Value)
             .Take(limit));

3 Banana    2016-03-04
7 Juice     2016-03-03
4 Potato    2016-03-02
5 Cafee     2016-03-01

问题在于性能,因为EF不支持SkipWhile,所以我必须先获取所有数据。
当然,我可以通过以下方式剪切所有旧行:
var banana = this.Db.Context.Items.FirstOrDefault(g => g.Id == 3);
var result = query.Where(g => g.CreatedAt < banana.CreatedAt).Take(limit);

是否可能通过单个、高效的 EF 查询实现这一点?


1
指定query.ToList()会强制EF对数据库运行查询。试试只使用.Skip(4)。你是想每次显示4个项目来分页列表吗? - Mihail Stancescu
我不知道应该跳过多少个元素。 - Rakoo
1个回答

3

两个语句并不总是比一个更复杂的语句表现得更差,但你可以这样做:

var result = query.Where(g => g.CreatedAt < 
                                  this.DbContext.Items.FirstOrDefault(g2 => g2.Id == 3)
                                 .CreatedAt)
                  .Take(limit);

事实上,这是我认为在与SQL兼容的方式下模仿SkipWhile行为的唯一可能性。
如果你真的非常关注性能,那么你应该将其与第二个(或最佳)选项进行比较。
var createdAt = this.Db.Context.Items
                    .Where(g => g.Id == 3)
                    .Select(g => g.CreatedAt)
                    .FirstOrDefault();
var result = query.Where(g => g.CreatedAt < createdAt).Take(limit);

这只从数据库中选择一个日期值,而不是完整的“项目(Item)”。

可能会有帮助。谢谢。 - Rakoo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接