У меня есть приложение, которое позволяет пользователям вводить время, которое они проводят, и я пытаюсь создать хорошую отчетность для этого, которая использует LINQ to Entities. Поскольку каждый TrackedTime
имеет TargetDate
, который является только частью "Дата" в DateTime
, относительно просто сопоставить время пользователя и дату (я просто оставляю предложения "where" для простоты)
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. Спасибо всем!