2012-02-22 36 views
0

我有按降序排列的文章列表。如果等級相同,它們是按升序編號排序(該ID是唯一的):LINQ to SQL SkipWhile在排序列中使用重複值實現

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

我要查詢3篇文章,這意味着在第一頁就會有第9條,第3和第6頁。這是通過查詢排序列表中排名前三位的文章完成的。

現在,我想從第8條開始,繼續使用文章ID作爲標記來恢復位置,而不是僅僅跳過前三條。這是因爲文章表的內容變化非常迅速,一個標準的分頁方法是這樣的:

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

將無法​​可靠地工作,因爲文章可以添加或刪除在任何時間(只是假設評級不會改變這裏)。

如果這是LINQ到對象,我會用SkipWhile

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

SkipWhile沒有在LINQ實施SQL(見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,從第8條恢復分頁的最佳方式是什麼?使用文章ID作爲標記恢復位置?

回答

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; 
    } 

,我覺得就可以了。

+0

不,因爲在我抓取第一頁後,某人可能已經插入或刪除了一行。在Skip()中使用固定數字時,可以跳過插入的行,或者可能導致後續行重複,刪除行可能導致後續行被跳過。 – 2012-02-22 13:24:54

+0

好吧我已經更新了我的答案 – Dave 2012-02-22 15:00:46

+0

謝謝,它的工作原理。 – 2012-02-22 15:36:20