2016-09-20 69 views
0

下面是我期待转换为LINQ查询转换总和(情况)SQL语句LINQ查询实体框架

SELECT 
    ProcessName, 
    SUM(CASE WHEN Status = 'In-Progress' THEN 1 ELSE 0 END) As 'In-Progress', 
    SUM(CASE WHEN Status = 'Success' THEN 1 ELSE 0 END) As 'Completed', 
    Count(CASE WHEN status in ('In-Progress','Success') then 1 end) as Total 
FROM 
    TableName 
GROUP BY 
    ProcessName 

回答

1

你可以做这样的事情,我的SQL查询:

var statuses = new {"In-Progress","Success"}; 


var res = yourData 
      .GroupBy(m => m.ProcessName) 
      .Select(g => new { 
      ProcessName = g.Key, 

      //for InProgress, 2 (or 3) ways 
      InProgress = g.Select(x => x.Status == "In-Progress" ? 1 : 0).Sum(), 
      //another way 
      InProgress = g.Where(x => x.Status == "In-Progress").Count(), 
      //another way, not sure if it works in linq to entities 
      InProgress = g.Count(x => x.Status == "In-Progress"), 

      //same 3 ways possible for completed, the first here 
      Completed = g.Select(x => x.status == "Success" ? 1 : 0).Sum(), 

      //for the count 
      //not sure if this one works in linq to entities 
      Total = g.Count(x => statuses.Contains(x.Status)) 
      //alternative 
      Total = g.Where(x => statuses.Contains(x.Status)).Count() 
      }); 
0
string statuses = new {"In-Progress","Success"}; 

var results = from item in TableName 
       group item by p.ProcessName into g 
       select new yourReturnType 
       { 
       ProcessName = g.Key, 
       In-Progress = g.Where(l=>l.Status == "In-Progress").Count(), 
       Completed = g.Where(l=>l.Status == "Success").Count(),      
       Total = g.Where(x => statuses.Contains(x.Status)).Count() 

       }; 
1

第一部分很简单。 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查询相同。

+0

很好的解释和尝试+1 :) – Sampath