Преобразование оператора SQL CASE WHEN и оператора группы в LINQ - PullRequest
3 голосов
/ 03 января 2012

Как я могу написать в свободном синтаксисе linq выражение "case when" sql?

select QueueItem, COUNT(*) as [Count],
SUM(CASE WHEN Queued = 0 THEN 1 ELSE 0 END) AS [Sent],
SUM(CASE WHEN Queued = 1 THEN 1 ELSE 0 END) AS Queued,
SUM(CASE WHEN Success = 1 THEN 1 ELSE 0 END) AS Exported,
SUM(CASE WHEN Success = 0 THEN 1 ELSE 0 END) AS Failed
from ExportQueue x
group by QueueItem

Есть ли какая-нибудь программа, которая может конвертировать SQL в LINQ?Может быть LinqPad?

Ответы [ 3 ]

4 голосов
/ 03 января 2012

Хорошо, как-то так.Мне понадобится немного информации, чтобы быть уверенным, хотя

В очереди немного?Это имеет значение в linq, а в SQL - нет.Я также не знаю ваших имен контекста, но вы должны понять.

var query = Context.ExportQueues.Select(x => new { 
  QueueItem = x.QueueItem, 
  Sent = !x.Queued ? 1 : 0,
  Queued = x.Queued ? 1 : 0,
  Exported = x.Success ? 1 : 0,
  Failed = !x.Success ? 1 : 0 })
.GroupBy(x => x.QueueItem)
.Select(g => new { 
  QueueItem = g.Key,
  Sent = g.Sum(x => x.Sent),
  Queued = g.Sum(x => x.Queued),
  Exported = g.Sum(x => x.Exported),
  Failed = g.Sum(x => x.Failed)
}).ToList();

РЕДАКТИРОВАТЬ Вы также можете объединить их, выполнив запрос на лету.Я всегда склонен записывать это, как указано выше, во время проработки, хотя более сложные агрегаты могут быть немного сложными для отладки, если есть ошибки:

var query = Context.ExportQueues
.GroupBy(x => x.QueueItem)
.Select(g => new { 
  QueueItem = g.Key,
  Sent = g.Sum(x => !x.Queued ? 1 : 0),
  Queued = g.Sum(x => x.Queued ? 1 : 0),
  Exported = g.Sum(x => x.Success ? 1 : 0),
  Failed = g.Sum(x => !x.Success ? 1 : 0 )
}).ToList();
2 голосов
/ 03 января 2012

В качестве альтернативы решению Gatts вы можете сделать что-то вроде

var query = Context.ExportQueues.
.GroupBy(x => x.QueueItem)
.Select(g => new { 
  QueueItem = g.Key,
  Sent = g.Count(x=>!x.Queued),
  Queued = g.Count(x => x.Queued),
  Exported = g.Count(x => x.Success),
  Failed = g.Count(x => !x.Failed)
}).ToList();
0 голосов
/ 03 января 2012

Это на самом деле довольно скучно писать с использованием LINQ. Вам нужно сначала сгруппировать, а затем использовать лямбда-выражения для обработки агрегации. Так что-то вроде:

from eq in ExportQueue
group eq by new {
    eq.QueueItem
} into temp
select new {
    temp.Key.QueueItem,
    Agg1 = temp.Sum(n => n.Queued == 0 ? 1 : 0),
    Agg2 = temp.Sum(n => n.Queued == 1 ? 1 : 0)
}

И так далее, LinqPad будет очень полезен при попытке заставить это работать.

...