如果我有一個包含1或NULL的標題列和3位列(f1,f2,f3)的表格,我如何編寫LINQ以返回標題和每個包含1的位列?我正在尋找相當於這個SQL查詢:多列LINQ COUNT
SELECT title, COUNT(f1), COUNT(f2), COUNT(f3) FROM myTable GROUP BY title
我正在尋找「最好」的方式來做到這一點。當我查看底層的SQL時,我想到了這個版本的4次下沉,所以它太慢了。
如果我有一個包含1或NULL的標題列和3位列(f1,f2,f3)的表格,我如何編寫LINQ以返回標題和每個包含1的位列?我正在尋找相當於這個SQL查詢:多列LINQ COUNT
SELECT title, COUNT(f1), COUNT(f2), COUNT(f3) FROM myTable GROUP BY title
我正在尋找「最好」的方式來做到這一點。當我查看底層的SQL時,我想到了這個版本的4次下沉,所以它太慢了。
下面是我提出的解決方案。請注意,這是接近的@OdeToCode(但在VB語法)提出的解決方案,有一個重要區別:
Dim temp = _
(From t In context.MyTable _
Group t.f1, t.f2, t.f3 By t.title Into g = Group _
Select title, g).ToList
Dim results = _
From t In temp _
Select t.title, _
f1_count = t.g.Count(Function(x) If(x.f1, False)), _
f2_count = t.g.Count(Function(x) If(x.f2, False)), _
f3_count = t.g.Count(Function(x) If(x.f3, False))
第一個查詢做了分組,但ToList獲取分組數據,從服務器。在這裏消除計數可以使生成的SQL語句不會爲每個計數生成子SELECT。我在本地查詢第二個查詢。
這是可行的,因爲我知道第一個查詢將返回一個可管理的行數。如果它返回數百萬行,我可能不得不朝另一個方向前進。
我認爲這是LINQ跌倒的地方。如果你想高效地使用SQL,如果你想要很好的代碼,可以使用LINQ。
由於您已經知道SQL,因此您可以始終直接執行查詢。
class TitleCount {
public string Title;
public int Count1;
public int Count2;
public int Count3;
}
DataContext dc = new DataContext("Connection string to db");
IEnumerable<TitleCount> query = dc.ExecuteQuery<TitleCount>(
@"SELECT title,
COUNT(f1) as Count1,
COUNT(f2) as Count2,
COUNT(f3) as Count3
FROM myTable GROUP BY title");
如果你想堅持到LINQ查詢和使用匿名類型,查詢可能看起來像:
var query =
from r in ctx.myTable
group r by r.title into rgroup
select new
{
Title = rgroup.Key,
F1Count = rgroup.Count(rg => rg.f1 == true),
F2Count = rgroup.Count(rg => rg.f2 == true),
F3Count = rgroup.Count(rg => rg.f3 == true)
};
關鍵是要認識到,要算真正的字段數(它被映射爲一個可爲空的bool),你可以用Count操作符和謂詞來完成。有關LINQ組運營商的更多信息,請點擊:The Standard LINQ Operators
這就是我最初想到的解決方案,但生成的查詢使用子選擇來生成每個單獨的計數。在一個有50萬行(沒有索引)的表上,這個版本需要7秒,而具有3個COUNT的適當的SQL是即時的。 – gfrizzle 2009-01-26 13:32:52
請勿將其用於大型數據集!請不要複製並粘貼到您的應用程序。這個答案應該有一個巨大的警告。 – 2014-12-17 19:38:30