2009-06-19 48 views
1

我最近編寫了一個LINQ查詢來獲取包含最近6個月的展示位置數量的Dictionary如何使這個LINQ查詢更清潔?

它返回月份字符串 - 十進制金額對的Dictionary

它似乎有點cirlify。你們中的任何一位LINQ大師能夠幫助我重構這一點,使其更清潔一些?

/// <summary> 
/// Gets the last 6 months of Placement History totalled by Month 
/// for all Agencies 
/// </summary> 
/// <returns></returns> 
public Dictionary<string, decimal> getRecentPlacementHistory() 
{ 
    var placementHistoryByMonth = new Dictionary<string, decimal>(); 

    using (DemoLinqDataContext db = new DemoLinqDataContext()) 
    { 
     for (int i = 0; i < 6; i++) 
     { 
      Decimal monthTotal = 
       (from a in db.Accounts 
       where 
       (a.Date_Assigned.Value.Month == DateTime.Now.AddMonths(-i).Month && 
        a.Date_Assigned.Value.Year == DateTime.Now.AddMonths(-i).Month) 
       select a.Amount_Assigned).Sum(); 
      String currentMonth = DateTime.Now.AddMonths(-i).ToString("MMM"); 

      placementHistoryByMonth.Add(currentMonth, monthTotal); 
     } 
     return placementHistoryByMonth; 
    } 
} 

回答

5

第一個問題:

where (a.Date_Assigned.Value.Month == DateTime.Now.AddMonths(-i).Month && 
     a.Date_Assigned.Value.Year == DateTime.Now.AddMonths(-i).Month) 

如果不是後者的表達與.Year而非.Month結束?當然,你很少會得到一個值爲1-12的年... ...

我會提取「當前月份」的想法,因爲你使用它很多。請注意,你也走的是當前的時間多次,如果它運行在在月末半夜能發出奇怪的結果...

public Dictionary<string, decimal> getRecentPlacementHistory() 
{ 
    var placementHistoryByMonth = new Dictionary<string, decimal>(); 
    using (DemoLinqDataContext db = new DemoLinqDataContext()) 
    { 
     DateTime now = DateTime.Now; 

     for (int i = 0; i < 6; i++) 
     { 
      DateTime selectedDate = now.AddMonths(-i); 

      Decimal monthTotal = 
       (from a in db.Accounts 
       where (a.Date_Assigned.Value.Month == selectedDate.Month && 
         a.Date_Assigned.Value.Year == selectedDate.Year) 
       select a.Amount_Assigned).Sum(); 

      placementHistoryByMonth.Add(selectedDate.ToString("MMM"), 
             monthTotal); 
     } 
     return placementHistoryByMonth; 
    } 
} 

我意識到這可能是你試圖循環擺脫。您可以嘗試制定整批貨物日期的上限和下限,然後根據相關範圍內的a.Date_Assigned年/月進行分組。說實話,它不會更漂亮。請注意,如果你能把它關閉,那隻會是對數據庫的一個查詢。

+1

selectedDate.Month.Year沒有很多意義...錯字? ;) – em70 2009-06-19 17:13:19

+0

@Jon Skeet,我該如何處理月份是一月份的情況。一旦我們從當前日期減去幾個月後,年度將不再匹配,並且此方法將失敗。我試圖找出如何解決這個問題,雖然每個月都不匹配。 – 2009-06-19 17:22:03

0

如果您不擔心沒有數據丟失的幾個月,然後我就在那裏我做了以下類似的問題:(翻譯成你的變量)

DateTime startPeriod = 
    new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1).AddMonths(-6); 

    var query1 = from a in db.Accounts where a.Date_Assigned >= startPeriod 
group a by new { a.Date_Assigned.Year ,a.Date_Assigned.Month } into result 
select new 
{ 
    dt = new DateTime(result.Key.Year, result.Key.Month , 1), 
    MonthTotal = result.Sum(i => i.Amount_Assigned) 
} ;    

    var dict = query1.OrderBy(p=> p.dt).ToDictionary(n => n.Dt.ToString("MMM") , n => n.MonthTotal); 
2

使用組通過

DateTime now = DateTime.Now; 
DateTime thisMonth = new DateTime(now.Year, now.Month, 1); 

Dictionary<string, decimal> dict; 
using (DemoLinqDataContext db = new DemoLinqDataContext()) 
{ 
    var monthlyTotal = from a in db.Accounts 
     where a.Date_Assigned > thisMonth.AddMonths(-6) 
     group a by new {a.Date_Assigned.Year, a.Date_Assigned.Month} into g 
     select new {Month = new DateTime(g.Key.Year, g.Key.Month, 1), 
        Total = g.Sum(a=>a.Amount_Assigned)}; 

    dict = monthlyTotal.OrderBy(p => p.Month).ToDictionary(n => n.Month.ToString("MMM"), n => n.Total); 
} 

無需循環!