2008-10-30 124 views
30

假設標籤的表像計算器的問題標籤:LINQ中「最受歡迎」GROUP BY?

標籤識別(BIGINT),QuestionID(BIGINT),標籤(VARCHAR)

什麼是最有效的方式,以獲得25個最使用LINQ的標籤?在SQL中,一個簡單的GROUP BY會做:

SELECT Tag, COUNT(Tag) FROM Tags GROUP BY Tag 

我已經寫了一些LINQ的作品:

var groups = from t in DataContext.Tags 
      group t by t.Tag into g 
      select new { Tag = g.Key, Frequency = g.Count() }; 
return groups.OrderByDescending(g => g.Frequency).Take(25); 

一樣,真的嗎?這不是特別冗長嗎?可悲的是,我這樣做是爲了節省大量的查詢,因爲我的Tag對象已經包含了一個Frequency屬性,否則如果我實際使用了該屬性,則該屬性將需要在數據庫中檢查每個Tag。

所以我然後分析這些匿名類型到標籤對象:

groups.OrderByDescending(g => g.Frequency).Take(25).ToList().ForEach(t => tags.Add(new Tag() 
{ 
    Tag = t.Tag, 
    Frequency = t.Frequency 
})); 

我是新手LINQ,這看起來不正確。請告訴我它是如何完成的。

+0

我相信你的SQL應該是`SELECT標記,COUNT(標記)FROM標記GROUP BY標記ORDER BY COUNT(標記)DESC FETCH FIRST 25 ROWS ONLY`,這不會讓Linq看起來那麼糟糕。 – NetMage 2016-10-07 00:17:23

回答

10

我很肯定你說得對。而且,LINQ生成併發送到你的數據庫的SQL看起來就像你開始使用的SQL,所以當你做更多的輸入時,你的數據庫不會再做任何工作。

24

如果你想要標籤對象,爲什麼不直接從你的Linq查詢中創建它們?

var groups = from t in DataContext.Tags 
      group t by t.Tag into g 
      select new Tag() { Tag = g.Key, Frequency = g.Count() }; 

return groups.OrderByDescending(g => g.Frequency).Take(25); 
+0

啊哈!這就是我想念的,謝謝! – tags2k 2008-10-30 17:08:29

+0

除此之外,我得到了「在查詢中不允許顯式構造實體類型」的錯誤。似乎你不能! – tags2k 2008-10-30 17:51:21

+0

我懷疑這是因爲Tag是一種數據上下文類型 - 您可以絕對使用其他類型,但是Linq顯然試圖保護您免於創建與數據上下文項不對應的Tag實例。 – GalacticCowboy 2008-10-30 19:35:06

12

如果您使用語法的詳細形式,您的代碼將是冗長的。這裏有一個選擇:

List<Tag> result = 
    db.Tags 
    .GroupBy(t => t.Tag) 
    .Select(g => new {Tag = g.Key, Frequency = g.Count()}) 
    .OrderByDescending(t => t.Frequency) 
    .Take(25) 
    .ToList() 
    .Select(t => new Tag(){Tag = t.Tag, Frequency = t.Frequency}) 
    .ToList(); 
3

我看你也是不公平的,你的SQL查詢不會做同樣的事情,你的LINQ查詢 - 它不返回前25