2010-01-20 39 views
5

我是新來的LINQ to SQL,我想知道如何實現在LINQ是這樣的:LINQ組按月問題

 Month Hires Terminations 
     Jan  5  7 
     Feb  8  8 
     Marc  8  5 

我這有,到目前爲止,我認爲有是不是有問題,但我不知道:

from term1 in HRSystemDB.Terminations 
group term1 by new { term1.TerminationDate.Month, term1.TerminationDate.Year } into grpTerm 
select new HiresVsTerminationsQuery 
{ 
    Date = Criteria.Period, 
    TerminationsCount = grpTerm.Count(term => term.TerminationDate.Month == Criteria.Period.Value.Month), 
    HiresCount = (from emp in HRSystemDB.Persons.OfType<Employee>() 
       group emp by new { emp.HireDate.Month, emp.HireDate.Year } into grpEmp 
       select grpEmp).Count(e => e.Key.Month == Criteria.Period.Value.Month) 
}); 

在此先感謝。

+0

向我們展示您的數據庫架構將有所幫助。 – Blindy 2010-01-20 21:51:32

+0

什麼是「Criteria.Period」和「Criteria.Period.Value.Month」? – 2010-01-20 21:52:45

+0

是什麼讓你感到不確定是對的?它是否編譯?你有沒有試過運行它?它是否提供您期望的結果? – 2010-01-20 21:58:36

回答

6

我不太確定Criteria.Period值來自您的示例查詢。

不過,我認爲你正在嘗試閱讀所有可用月份的僱用和終止(然後你可以很容易地過濾它)。如果第一個表(終止)沒有包含某個指定月份的任何記錄(如May),那麼您的查詢可能會出錯。那麼select子句將不會以「May」作爲參數調用,即使您在第二個表中有一些數據(表示Hires),那麼您也無法找到它。

這可以使用Concat method(請參閱MSDN示例)來優雅地解決。您可以通過選擇每月所有termniations和所有員工(成某種類型的數據結構),然後組中的所有數據:

var terms = from t in HRSystemDB.Terminations 
      select new { Month = t.TerminationDate.Month, 
         Year = term1.TerminationDate.Year, 
         IsHire = false }; 
var hires = from emp in HRSystemDB.Persons.OfType<Employee>() 
      select new { Month = emp.HireDate.Month, 
         Year = emp.HireDate.Year 
         IsHire = true }; 

// Now we can merge the two inputs into one 
var summary = terms.Concat(hires); 

// And group the data using month or year 
var res = from s in summary 
      group s by new { s.Year, s.Month } into g 
      select new { Period = g.Key, 
         Hires = g.Count(info => info.IsHire), 
         Terminations = g.Count(info => !info.IsHire) } 

當代碼現在看,我敢肯定有一些簡短的形式寫這個。另一方面,這個代碼應該是很可讀的,這是一個好處。另請注意,我們將代碼拆分爲幾個子查詢並不重要。感謝LINQ to SQL的懶惰評估,這應該作爲單個查詢來執行。

+0

這確實是一個很好的答案。我不知道concat方法。我將在稍後嘗試併發布我的結果。謝謝。 – jasonco 2010-01-20 22:28:05

+0

你救了我的命。工作很棒!正是我在找的東西。謝謝! +1 – jasonco 2010-01-21 18:18:44

3

我不知道它是否更短,但你也可以試試這個版本,看看它是否更適合你的服務器。我不知道這兩個答案是如何轉化爲SQL語句的。根據你的指數等可能會更好。

var terms = 
    from t in Terminations 
    group t by new {t.Month, t.Year} into g 
    select new {g.Key, Count = g.Count()}; 

var hires = 
    from p in Persons 
    group p by new {p.Month, p.Year} into g 
    select new {g.Key, Count = g.Count()}; 

var summary = 
    from t in terms 
    join h in hires on t.Key equals h.Key 
    select new {t.Key.Month, t.Key.Year, 
     Hires = h.Count, Terms = t.Count}; 
+0

感謝您的回答。只要在同一個月內有任何終止或僱用,此版本就可以工作。如果他們中沒有任何一個僱傭或者終止,那麼即使在5月份僱傭了2名僱員,但是終止僱傭關係,也沒有結果出現在特定月份。我不得不做出一個小小的更正,這個羣組(由於我的具體情況)應該是 「group t by new {t.TerminationDate.Month,t.TerminationDate.Year} into g」和「group p by new {p。 HireDate.Month,p.HireDate.Year}成g「。除此之外,我認爲這是一個很好的答案。謝謝! +1 :-) – jasonco 2010-01-21 18:16:56