多列上的LINQ COUNT

时间:2009-01-23 22:11:17

标签: .net sql linq linq-to-sql

如果我有一个包含标题列和3位列(f1,f2,f3)的表,其中包含1或NULL,我将如何编写LINQ以返回包含1的每个位列的计数的标题?我正在寻找相当于这个SQL查询:

SELECT title, COUNT(f1), COUNT(f2), COUNT(f3) FROM myTable GROUP BY title

我正在寻找“最好”的方式来做到这一点。当你查看基础SQL时,我想出的版本会在表中蘸4次,所以它太慢了。

3 个答案:

答案 0 :(得分:4)

如果您想坚持使用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

答案 1 :(得分:2)

我认为这是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");

答案 2 :(得分:0)

这是我提出的解决方案。请注意,它接近@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。我在本地第二个查询中进行计数。

这是有效的,因为我知道第一个查询将返回可管理的行数。如果它返回数百万行,我可能不得不朝另一个方向前进。