Не используйте это для больших наборов данных! Пожалуйста, просто не копируйте и не вставляйте это в свое приложение. Там должно быть огромное предупреждение об этом ответе.

у меня есть таблица со столбцом заголовка и 3-битными столбцами (f1, f2, f3), которые содержат либо 1, либо NULL, как бы я написал LINQ, чтобы вернуть заголовок с счетчиком каждого битового столбца, который содержит 1? Я ищу эквивалент этого запроса SQL:

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

Я ищу "лучший" способ сделать это. Версия, которую я придумал, погружается в таблицу 4 раза, когда вы смотрите на базовый SQL, поэтому он слишком медленный.

Ответы на вопрос(3)

Решение Вопроса

которое я придумал. Обратите внимание, что оно близко к решению, предложенному @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 для каждого подсчета. Я делаю подсчет во втором запросе локально.

Это работает, так как я знаю, что первый запрос вернет управляемое количество строк. Если бы он возвращал миллионы строк, мне, вероятно, пришлось бы идти в другом направлении.

 Rush Frisby17 дек. 2014 г., 20:38
Не используйте это для больших наборов данных! Пожалуйста, просто не копируйте и не вставляйте это в свое приложение. Там должно быть огромное предупреждение об этом ответе.

что это где 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");

п, запрос может выглядеть следующим образом:

 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 здесь:Стандартные операторы LINQ

 gfrizzle26 янв. 2009 г., 14:32
Это решение, которое я придумал изначально, но в итоговом запросе используются субвыборы для получения каждого отдельного счета. В таблице с полмиллионом строк (без индексов) эта версия занимает 7 секунд, в то время как правильный SQL с 3 COUNT выполняется мгновенно.

Ваш ответ на вопрос