У меня есть приложение, которое позволяет пользователям вводить время, которое они проводят за работой, и я пытаюсь создать для этого хорошую отчетность, которая использует LINQ to Entities. Поскольку каждый TrackedTime
имеет TargetDate
, который является просто частью "Дата" в DateTime
, относительно просто сгруппировать время по пользователю и дате (я опускаю предложения "где" для простоты) :
var userTimes = from t in context.TrackedTimes
group t by new {t.User.UserName, t.TargetDate} into ut
select new
{
UserName = ut.Key.UserName,
TargetDate = ut.Key.TargetDate,
Minutes = ut.Sum(t => t.Minutes)
};
Благодаря свойству DateTime.Month
группировка по пользователю и месяцу лишь немного сложнее:
var userTimes = from t in context.TrackedTimes
group t by new {t.User.UserName, t.TargetDate.Month} into ut
select new
{
UserName = ut.Key.UserName,
MonthNumber = ut.Key.Month,
Minutes = ut.Sum(t => t.Minutes)
};
Теперь самое сложное. Есть ли надежный способ группировки по неделям? Я попробовал следующее на основе этого ответа на похожий вопрос LINQ to SQL:
DateTime firstDay = GetFirstDayOfFirstWeekOfYear();
var userTimes = from t in context.TrackedTimes
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)
};
Но LINQ to Entities не поддерживает арифметические операции над объектами DateTime, поэтому не знает, как это сделать (t.TargetDate - firstDay).Days / 7
.
Я подумал о создании представления в базе данных, которое просто отображает дни в недели, а затем добавляет это представление в мой контекст Entity Framework и присоединяется к нему в моем запросе LINQ, но это похоже на большую работу для чего-то вроде этот. Есть ли хороший обходной путь для арифметического подхода? Что-то, что работает с Linq to Entities, что я могу просто включить в оператор LINQ, не касаясь базы данных? Какой-нибудь способ рассказать Linq Entities, как вычесть одну дату из другой?
Краткое описание
Я хотел бы поблагодарить всех за их вдумчивые и творческие ответы. После всего этого, похоже, реальный ответ на этот вопрос - «подождите до .NET 4.0». Я собираюсь отдать награду Нолдорину за самый практичный ответ, который до сих пор использует LINQ, и особенно упомянуть Джейкоба Проффитта за то, что он придумал ответ, который использует Entity Framework без необходимости изменений на стороне базы данных. Были и другие отличные ответы, и если вы смотрите на вопрос впервые, я настоятельно рекомендую прочитать все те, за которые проголосовали, а также их комментарии. Это действительно был превосходный пример силы StackOverflow. Спасибо всем!