实体框架 - SkipWhile

时间:2016-03-26 13:54:40

标签: sql-server entity-framework linq

我按照desc date排序了以下行:

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 个答案:

答案 0 :(得分:2)

两个陈述总是比一个更复杂的陈述表现更差,但你可以这样做:

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