[英]How can I make this LINQ query cleaner?
我最近寫了一個LINQ查詢來獲取包含最近6個月的刊登位置數量的Dictionary
。
它返回一個月Dictionary
字符串-小數對。
似乎有點笨拙。 你們中的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;
}
}
第一個問題:
where (a.Date_Assigned.Value.Month == DateTime.Now.AddMonths(-i).Month &&
a.Date_Assigned.Value.Year == DateTime.Now.AddMonths(-i).Month)
后一個表達式不應該以.Year而不是.Mon結尾嗎? 當然,您很少會得到價值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
的年/月分組。 老實說,這不會太漂亮。 請注意,如果可以進行查詢,那只會是對數據庫的一個查詢。
使用分組依據
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);
}
無需循環!
如果您不擔心缺少數據的月份,那么我在執行以下操作時也會遇到類似的問題:(轉換為您的變量)
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 );
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.