2012-01-03 134 views
3

如何使用流畅的linq语法编写“case when”sql语句?将SQL CASE WHEN语句和组语句转换为LINQ

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也许?

+0

它在LINQ令人惊讶更复杂的做到这一点。在某件事情的中间,但如果你还没有解决方案,我会在大约30分钟后回复并写出来。关键是把你的情况变成匿名结果,然后再把你的情况变成一团糟。 – Gats 2012-01-03 11:16:57

+0

谢谢。如果查询不清楚,查询的目的是按队列项目(销售/信用/购买/等)进行分组,并报告发送了多少,队列中剩余多少,成功和有多少次失败 – 2012-01-03 11:24:23

+0

是的那。我想帮助,因为我喜欢你使用Sum和case的方式。这也是我的一个古老的伎俩,我很惊讶人们不会使用更多,因为它非常快。你需要记住linq显然会做得更慢。我仍然喜欢存储过程对于复杂的聚合,因为左连接的情况可以很容易失控,但这应该没问题。 – Gats 2012-01-03 11:29:53

回答

4

好吧,这样的事情。我需要一些信息来确定,但

排队了一下吗?这在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(); 
+0

不错的解决方案! – 2012-01-03 11:35:53

+0

它们实际上是可空的位域,所以我改变了你的'Sent =!x.Queued? 1:0'变成'Sent = x.Queued!= true? 1:0“等。但分组不起作用,它每行返回一组。 – 2012-01-03 11:37:09

+0

我在QueueItem = x上犯了一个错误。编辑版应该更好。 QueueItem = x.QueueItem, – Gats 2012-01-03 11:38:18

0

这其实很啰嗦使用LINQ编写。你需要做的是首先进行分组,然后使用lambda表达式来处理聚合。所以像这样:

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将是非常有用的试图让这个工作。

2

作为一种替代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

这应该也可以,虽然我认为它最终可能会生成更多的子查询。我会尝试它们,并在我获得时间时进行描述,因为这很有趣。 – Gats 2012-01-03 11:41:55

+1

Plz让我们知道当你完成它 – 2012-01-03 11:44:13

+0

+1也是一个非常好的方法 – 2012-01-03 11:53:39