第一部分很简单。 SQL表达式SUM(CASE WHEN condition THEN 1 ELSE 0 END)
直接映射到LINQ Sum(condition ? 1 : 0)
。
更有趣的是SQL表达式COUNT(CASE WHEN condition THEN 1 END
。这是COUNT(CASE WHEN condition THEN 1 ELSE NULL END
的快捷方式。现在,考虑到SQL COUNT
函数跳过NULL值,LINQ映射可能是Count(condition)
或Sum(condition ? 1 : 0)
。根据我对EF的经验,后者转换为更好的SQL(前者从源表中生成额外的子查询读取),所以我总是更喜欢LINQ to Entities查询。
有了这样说,LINQ查询可能是这样的:
// constants to avoid typos
const string StatusInProgress = "In-Progress";
const string StatusCompleted = "Success";
// needed for IN clause
var statuses = new[] { StatusInProgress, StatusCompleted };
// the query
var query =
from e in db.TableA
group e by e.ProcessName into g
select new
{
InProgress = g.Sum(e => e.Status == StatusInProgress ? 1 : 0),
Completed = g.Sum(e => e.Status == StatusCompleted ? 1 : 0),
C = g.Sum(e => statuses.Contains(e.Status) ? 1 : 0),
};
和生成的SQL是这样的:
SELECT
1 AS [C1],
[GroupBy1].[K1] AS [ProcessName],
[GroupBy1].[A1] AS [C2],
[GroupBy1].[A2] AS [C3],
[GroupBy1].[A3] AS [C4]
FROM (SELECT
[Extent1].[K1] AS [K1],
SUM([Extent1].[A1]) AS [A1],
SUM([Extent1].[A2]) AS [A2],
SUM([Extent1].[A3]) AS [A3]
FROM (SELECT
[Extent1].[ProcessName] AS [K1],
CASE WHEN (N'In-Progress' = [Extent1].[Status]) THEN 1 ELSE 0 END AS [A1],
CASE WHEN (N'Success' = [Extent1].[Status]) THEN 1 ELSE 0 END AS [A2],
CASE WHEN ([Extent1].[Status] IN (N'In-Progress', N'Success')) THEN 1 ELSE 0 END AS [A3]
FROM [dbo].[TableName] AS [Extent1]
) AS [Extent1]
GROUP BY [K1]
) AS [GroupBy1]
正如你所看到的,除了丑外部分那什么也不做,最里面的子查询中包含的主要部分几乎与所讨论的SQL查询相同。
很好的解释和尝试+1 :) – Sampath