LINQ to SQL SkipWhile实现在排序列中具有重复值

时间:2012-02-22 13:15:33

标签: c# sql linq linq-to-sql linq-to-objects

我有按降序排序的文章列表。如果评级相同,则按升序ID排序(ID是唯一的):

ID      RATING
9       34
3       32
6       32
8       32
12      32
1       25
2       23

我想查询3篇文章的页面,这意味着第一页将有文章9,3和6.这是通过查询排序列表中的前3篇文章来完成的。

现在,我想从第8条继续接下来的3篇文章,使用文章ID作为恢复位置的标记,而不是仅仅跳过前3篇文章。这是因为文章表的内容变化非常快,并且标准的分页方法如下:

var articles = 
    db.Articles
    .OrderByDescending(a => a.Rating).ThenBy(a => a.Id)
    .Skip(3)
    .Take(3);

无法可靠地运作,因为可以随时添加或删除文章(只是假设评价在这里没有变化)。

如果这是LINQ to Object,我可以使用SkipWhile

var articles = 
    db.Articles
    .OrderByDescending(a => a.Rating).ThenBy(a => a.Id)
    .SkipWhile(a => a.Article.Id != 8)
    .Take(3);

但LINQ to SQL中未实现SkipWhile(请参阅here)。

如果我这样做:

var articles = 
    db.Articles
    .Where(a => a.Rating 
             < db.Articles.Single(aa => aa.Id == 8).Rating)
    .OrderByDescending(a => a.Rating)
    .Take(3);

我会跳过第12条,如果我做了这样的事情:

var articles = 
    db.Articles
    .Where(a => a.Rating 
             <= db.Articles.Single(aa => aa.Id == 8).Rating)
    .OrderByDescending(a => a.Rating)
    .Take(3);

我会两次接受第3和第6条。

使用LINQ to SQL,使用文章ID作为恢复位置的标记,从第8条恢复分页的最佳方法是什么?

1 个答案:

答案 0 :(得分:1)

你能做到:

var articles = 
db.Articles
.OrderByDescending(a => a.Rating).ThenBy(a => a.Id)
.Skip(3)
.Take(3);

好的,如果那不起作用,我会写一个像这样的函数:

    static IEnumerable<Article> GetArticles(List<Article> articles, int articlesToRetrieve, int startingID)
    {
        IEnumerable<Article> results = null;
        results = articles.OrderByDescending(a => a.Rating).ThenBy(a => a.ID);

        if (startingID > 0)
        {
            int lastRating = articles.Single(aa => aa.ID == startingID).Rating;
            results = results.Where(a => a.Rating < lastRating || (a.Rating == lastRating && a.ID > startingID));
        }

        if (articlesToRetrieve > 0)
        {
            results = results.Take(articlesToRetrieve);
        }
        return results;
    }

我认为这会解决问题。