2017-08-25 142 views
4

我有一個枚舉LINQ和枚舉與左連接

public enum Status { New, InProgress, Processed, InComplete}; 

我有以下查詢來查詢給我基於狀態列表計數。但現在我只有在它存在的情況下才能獲得。所以如果Processed計數爲零,我不會得到任何值。在SQL中,我會做一個左連接,但不太清楚在LINQ中如何做到這一點。也不知道如何做一個枚舉類型的左連接。

這裏是我的查詢

var results = DbContext.Orders 
         .Where(i => i.Id== Id) 
         .GroupBy(row => new { row.Status}) 
         .Select(g => new Stats() 
         { 
          Status = g.Key.Status, 
          Count = g.Count() 
         }).ToList(); 

所以在SQL我會做這樣的事情。假設我有一個狀態表。

SELECT status_id, s.name, count(status_id) count 
FROM order o LEFT JOIN status s ON (o.status_id = s.status_id) 
WHERE o.id = 1 
GROUP BY status_id, s.name 

我假設我會得到這樣的 新11個 INPROGRESS 5 加工0 不全0

在我的LINQ查詢我不會得到新的加工或不完整的結果。

+0

「row.Status」的類型是什麼?數據庫中是否有包含您提到的狀態的表格?如果是的話,這個表的列是什麼,以及如何與訂單相關聯,邏輯上必須存在從訂單到狀態的FK約束?謝謝 – Christos

+0

row.Status是枚舉值相等。所以1 =新,2 =進展中,3 =處理,4 =未完成。沒有桌子。我只有枚舉類型。 – MindGame

+0

正如以下鏈接所述https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/enum,*默認情況下,第一個枚舉數的值爲0,並且值每個連續的枚舉數增加1. *表示New的值爲0,InProgress的值爲1等。 – Christos

回答

4

一種方法是運行在數據庫中選擇,讓您目前的結果,然後通過連接在內存中枚舉,這樣填空:

// This selection is performed in the database 
var raw = DbContext.Orders 
    .Where(i => i.Id== Id) 
    .GroupBy(row => new { row.Status }) 
    .Select(g => new Stats { 
     Status = g.Key.Status, 
     Count = g.Count() 
    }).ToList(); 
// This join is performed in memory 
var results = 
    from e in Enum.GetValues(typeof(Status)).Cast<Status>() 
    join r in raw on e equals r.Status into rs 
    from r in rs.DefaultIfEmpty() 
    select new { Status = e, Count = r?.Count ?? 0}; 

由於數據傳輸到量來自RDBMS的內存不會改變,加入內存不會爲此操作的總體成本帶來重大變化。