2016-09-20 9 views
0

私はLINQクエリLINQクエリの合計(ケース)SQL文は以下

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

良い説明と試してみてください:) – Sampath