不支持Take
和Skip
?
LINQ的美妙之处在于,您可以用q.Skip(50).Take(50)
来描述这个复杂的排序标准和刚才所说的结果。如果每个页面显示50个结果,那么这将带您进入第二页。当然,它转换为有效的T-SQL,它使用ROW_NUMBER
窗口函数指示数据库使用您指定的顺序查找结果。
你甚至可以有一个非常复杂的查询与大量的过滤器。最终的结果仍然可以管理,因为您要么有行,要么不行。所有你需要考虑的是结果可能是空的。
关于身份的说明,因为拉迪斯拉夫指出,在完全相同的排序键(即日期和时间都为空)的条目之间不保证顺序。所以你要做的是添加一个身份列,这是你最不重要的排序列。没有身份的日志表/实体有时会被认为设计不当,因为当Date和Time可能为空时,数据的增长是不可预测的。这会导致页面拆分不良。经验法则是表应该有一个狭窄而唯一的集群主键。身份专栏非常适合这一点。它还将确保插入是快速操作,这是您的日志表将会欣赏的事情。
随着视图的帮助下,你可以把订单和ROW_NUMBER东西在普通T-SQL然后查询,使用EF这样的:
var q = from x in source
join y in source on x.RowNumber equals y.RowNumber - 1 into prev
join z in source on x.RowNumber equals z.RowNumber + 1 into next
from p in prev.DefaultIfEmpty()
from n in next.DefaultIfEmpty()
select new { Current = x, Previous = p, Next = n }
;
...或可能:
var q = from x in source
join y in source on x.RowNumber equals y.RowNumber - 1 into prev
join z in source on x.RowNumber equals z.RowNumber + 1 into next
select new {
Current = x,
Previous = prev.DefaultIfEmpty(),
Next = next.DefaultIfEmpty()
}
;
如果数据和时间都为空,则不能保证上一个和下一个值实际上是当前记录的上一个和下一个日志记录。 – 2011-03-21 18:44:37
为了保证一个稳定的订单,如果两行中的日期和时间相等(包括它们都为空),我将回退到行ID。我已经更新了这个问题,谢谢。 – 2011-03-21 19:15:01
所以不会像这样的工作? '.OrderBy(x => x.Id).FirstOrDefault(x => x.Id> currentSequenceId)'这就是说给我当前记录的'ID',我会在数据库中搜索更大的第一条记录比你给我的身份证。 – 2012-09-28 04:00:38