Group by Weeks in LINQ to Entities

Solution 1:

You should be able to force the query to use LINQ to Objects rather than LINQ to Entities for the grouping, using a call to the AsEnumerable extension method.

Try the following:

DateTime firstDay = GetFirstDayOfFirstWeekOfYear();
var userTimes = 
    from t in context.TrackedTimes.Where(myPredicateHere).AsEnumerable()
    group t by new {t.User.UserName, WeekNumber = (t.TargetDate - firstDay).Days / 7} into ut
    select new
    {
        UserName = ut.Key.UserName,
        WeekNumber = ut.Key.WeekNumber,
        Minutes = ut.Sum(t => t.Minutes)
    };

This would at least mean that the where clause gets executed by LINQ to Entities, but the group clause, which is too complex for Entities to handle, gets done by LINQ to Objects.

Let me know if you have any luck with that.

Update

Here's another suggestion, which might allow you to use LINQ to Entities for the whole thing.

(t.TargetDate.Days - firstDay.Days) / 7

This simply expands the operation so that only integer subtraction is performed rather than DateTime subtraction.

It is currently untested, so it may or may not work...

Solution 2:

You can use SQL functions also in the LINQ as long as you are using SQLServer:

using System.Data.Objects.SqlClient;

var codes = (from c in _twsEntities.PromoHistory
                         where (c.UserId == userId)
                         group c by SqlFunctions.DatePart("wk", c.DateAdded) into g
                         let MaxDate = g.Max(c => SqlFunctions.DatePart("wk",c.DateAdded))
                         let Count = g.Count()
                         orderby MaxDate
                         select new { g.Key, MaxDate, Count }).ToList();

This sample was adapted from MVP Zeeshan Hirani in this thread: a MSDN

Solution 3:

I had exactly this problem in my Time tracking application which needs to report tasks by week. I tried the arithmetic approach but failed to get anything reasonable working. I ended-up just adding a new column to the database with the week number in it and calculating this for each new row. Suddenly all the pain went away. I hated doing this as I am a great believer in DRY but I needed to make progress. Not the answer you want but another users point of view. I will be watching this for a decent answer.