I have recently written a LINQ query to get a Dictionary containing the last 6 month’s placement amounts.
It is returning a Dictionary of Month string – Decimal Amount pairs.
It seems kind of cludgey. Any of you LINQ masters out there able to help me refactor this to make a bit cleaner?
/// <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;
}
}
First problem:
Shouldn’t the latter expression end with .Year rather than .Month? Surely you’ll rarely get a year with a value of 1-12…
I would extract the idea of the “current month” as you’re using it a lot. Note that you’re also taking the current time multiple times, which could give odd results if it runs at midnight at the end of a month…
I realise it’s probably the loop that you were trying to get rid of. You could try working out the upper and lower bounds of the dates for the whole lot, then grouping by the year/month of
a.Date_Assignedwithin the relevant bounds. It won’t be much prettier though, to be honest. Mind you, that would only be one query to the database, if you could pull it off.