2014-01-31 192 views
1

的數量來選擇母行的次序最好的方式,我有我的表註釋像以下:的Linq:兒童

Comment{ 
ID, 
Text, 
ParentID 
} 

我使用下面的查詢基於回覆數字選擇分頁熱門評論。

var comments = db.Comments 
.OrderByDescending(c => db.Comments.Count(r => r.ParentID == c.ID)).Skip(skip).Take(recordsPerPage).ToList(); 

請讓我知道處理這種情況的最佳方式,當我們有成千上萬的評論?

+1

你有沒有考慮增加一個額外的列到'評論'存儲回覆計數? –

+1

我認爲您在訂購前跳過並採取措施,可能會給您錯誤的結果。 – drw85

+0

@ drw8你可能是對的我想。我會看看我的原始代碼是否如此。 – user3219798

回答

2

我會考慮增加一個額外的列Comment存儲的答覆計數。然後,而不是做一個嵌套的查詢,你可以輕鬆地按回復計數您的Comments

var comments = db.Comments.Skip(skip).Take(recordsPerPage) 
       .OrderByDescending(c => c.ReplyCount) 
       .ToList(); 
+0

我已經考慮過添加一個列,但是我必須在每次回覆被主持,標記或刪除時重新計算ReplyCount ..這又是一種開銷,所以我想如果有一種使用linq的最佳方式。 – user3219798

+0

我明白了,但它不應該是一個開銷,你只需要更新一個評論回覆計數,每次回覆是主持,標記或刪除..我認爲這是合理的比較在你目前的情況 –

+0

我想我會做現在回覆計數,除非有人發佈更好更簡單的方法。 – user3219798

1

除非你準備在數據庫中預先計算這點,你有,你需要做的任何嵌套查詢或者做一個全取內存中的,然後盡一切問題。後者是我的選擇,直到它被證明太慢。

下面是我最初的做法。

首先,預取:

var allComments = Comments.ToArray(); 

然後創建一個可快速返回的評論計數功能:

var childrenLookup = allComments.ToLookup(x => x.ParentID); 
var parentMap = allComments.ToDictionary(x => x.ID, x => x.ParentID); 

Func<int, int> getCommentsCount = n => 
{ 
    var r = 0; 
    if (parentMap.ContainsKey(n)) 
    { 
     r = childrenLookup[parentMap[n]].Count(); 
    } 
    return r; 
}; 

現在它幾乎是微不足道的返回結果:

var comments = allComments 
    .OrderByDescending(c => getCommentsCount(c.ID)) 
    .Skip(skip) 
    .Take(recordsPerPage) 
    .ToList(); 

(並且,是的,您的訂購順序錯誤,您可以跳過並尋求分頁。)

如果你不能在內存中執行此操作,請使用預先計算的方法。

+0

感謝您的回答,我想我會預先計算這個項目,但肯定會考慮這種方法。謝謝!! – user3219798