分页动态查询结果

时间:2013-08-28 17:30:42

标签: sql linq entity-framework asp.net-web-api

使用Skip()Take()扩展可以轻松完成使用LINQ的分页。
我一直在摸不着头脑,试图找到一种很好的方法来执行动态实体集合的分页 - 即可以在两个连续查询之间切换的集合。

假设没有分页的query将返回20个MyEntity类型的对象 以下两行将触发两个数据库匹配,这些命中将使用数据集中的所有对象填充results1results2

List<MyEntity> results1 = query.Take(10).ToList();
List<MyEntity> results2 = query.Skip(10).Take(10).ToList();

现在让我们假设数据是动态的,并且在两个查询之间将新的MyEntity插入到数据库中,这样原始查询就会将新实体放在第一个< / strong> page。
在这种情况下,results2列表将包含results1中存在的实体,
导致重复的结果被发送给查询的消费者。

假设第一页中的记录已删除,则会导致错过最初应显示在results2上的记录。

我考虑过在查询中添加一个Where()子句来验证在前一页上没有检索到的记录,但这似乎是错误的方法,并且对第二种方案没有帮助

我考虑过保留查询执行时间戳的记录,将LastUpdatedTimestamp附加到每个实体并过滤在上一页请求之后更改的实体。那个方向将在之后的第三页失败......

这通常是怎么做的?
有没有办法针对数据库的旧快照运行查询?

修改 后台是一个Asp.NET MVC WebApi服务,它响应一个简单的GET请求来检索实体列表。客户端检索实体页面,并将其呈现给用户。向下滚动时,客户端向服务发送另一个请求,以检索另一个实体页面,这些实体应该添加到已经呈现给用户的第一页。

1 个答案:

答案 0 :(得分:0)

解决此问题的一种方法是保留第一个查询的TimeStamp并排除在该时间之后添加的任何结果。然而,这个解决方案将数据置于“陈旧”状态,即数据在某个时间点固定,这通常是个坏主意,除非你有充分的理由去做。

另一种方法(再次取决于你的应用程序)是将所有对象的列表存储在内存中,然后一次只显示一定数量的结果。

List<Entity> _list;
public class SomeCtor()
{
    _list = _db.Entities.ToList();
}
public List<Entity> GetFirst10
{
    get
    {
        return _list.Take(10);
    }
}
public List<Entity> GetSecond10
{
    get
    {
        return _list.Skip(10).Take(10);
    }
}