Question

How can I write in fluent linq syntax the "case when" sql statement?

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

Is there some program that can convert SQL to LINQ? LinqPad maybe?

Was it helpful?

Solution

Ok, something like this. I'll need a bit of info to be sure though

Is Queued a bit? That makes a difference in linq where it doesn't in SQL. I also don't know your context names but you should get the idea.

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();

EDIT You could also combine these by doing the case on the fly in the query. I always tend to write it out as above first as I work through it though as more complex aggregates can be a bit hard to debug if there's errors:

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();

OTHER TIPS

As an alternative to Gatts solution you can do something like

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();

This is actually quite long-winded to write using LINQ. What you will need to do is to group first and then use lambda expressions to handle the aggregation. So something like:

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)
}

And so on, LinqPad will be really useful in trying to get this to work.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top