Reputation: 707
Given a table like this:
UserID,DateOfEntry,TimeWorked,Status
user1,2013-04-23,5,Submitted
user1,2013-04-22,7,Submitted
user1,2013-04-29,11,Submitted
user1,2013-04-24,3,Approved
user2,2013-04-22,9,Submitted
How would I go about getting this result set:
UserID,WeekStart,SumTimeWorked
user1, 2013-04-21, 12
user1, 2013-04-28, 11
user2, 2013-04-21, 9
Where the grouping is based on the userID, and the Sunday preceding the date in "DateOfEntry"?
I would prefer Lambda syntax if possible.
EDIT Here's the working query, based on Thomas' answer. This is the actual query for the actual table I'm querying, so it might not match the above example exactly.
var entries = _db.TimeEntries.GroupBy(g => new {
weekstart = g.DateOfEntry.AddDays(-(int)g.DateOfEntry.DayOfWeek),
userID = g.UserID
})
.OrderBy(c => c.Key.userID)
.Select(c => new {
userID = c.Key.userID,
weekStart = c.Key.weekstart,
Duration = c.Sum(sub => sub.Duration)
});
EDIT 2 The above Query worked in LINQPad and the actual code it is used in wasn't ready to be tested until today - unfortunately in LINQPad I was using LINQ to SQL and in code we're using LINQ to Entities. I receive this error now, if anyone has any ideas...
LINQ to Entities does not recognize the method 'System.DateTime AddDays(Double)'
method, and this method cannot be translated into a store expression.
EDIT 3 Ok, I think I've got this one figured out. I had to add two Using statements:
using System.Data.Objects;
using System.Data.Objects.SqlClient;
and then change the query to:
var entries = _db.TimeEntries.GroupBy(g => new {
weekstart = EntityFunctions.AddDays(g.DateOfEntry, -SqlFunctions.DatePart("weekday", g.DateOfEntry)),
userID = g.UserID
})
.OrderBy(c => c.Key.userID)
.Select(c => new {
userID = c.Key.userID,
weekStart = c.Key.weekstart,
Duration = c.Sum(sub => sub.Duration)
});
Sources: Linq to EntityFramework DateTime and LINQ to Entities Join on DateTime.DayOfWeek
Upvotes: 1
Views: 95
Reputation: 14565
The linq query is quite simple actually:
var q = from s in submissions
group s by GetKey(s) into g
select new
{
UserId = g.Key.Key,
WeekStart = g.Key.Value,
SumTimeWorked = g.Sum(sub => sub.TimeWorked)
};
The trick is to define an appropriate grouping method. This one uses KeyValuePairs just because I didn't want to throw in a class definition in this answer:
private KeyValuePair<string, DateTime> GetKey(Submission s)
{
return new KeyValuePair<string, DateTime>
(s.UserID, s.DateOfEntry.AddDays(-(int)s.DateOfEntry.DayOfWeek));
}
By the way, after running it I noticed that one of your rows has the wrong value in the SumTimeWorked column. It should be:
user1, 2013-04-21, 15
Upvotes: 1