Str*_*ior 39 c# linq linq-to-entities entity-framework
我有一个应用程序,允许用户输入他们工作的时间,我正在尝试为此构建一个良好的报告,利用LINQ to Entities.因为每个TrackedTime都TargetDate只是a的"Date"部分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)
};
Run Code Online (Sandbox Code Playgroud)
由于该DateTime.Month属性,按用户分组和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)
};
Run Code Online (Sandbox Code Playgroud)
现在是棘手的部分.是否有可靠的方式按周分组?我根据对类似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)
};
Run Code Online (Sandbox Code Playgroud)
但LINQ to Entities似乎不支持DateTime对象的算术运算,因此它不知道该怎么做(t.TargetDate - firstDay).Days / 7.
我考虑在数据库中创建一个只需几天到几周的视图,然后将该视图添加到我的实体框架上下文并在我的LINQ查询中加入它,但这似乎是很多工作.算术方法有一个很好的解决方法吗?与Linq to Entities一起使用的东西,我可以简单地将其合并到LINQ语句中而无需触及数据库?某种方式告诉Linq实体如何从另一个中减去一个日期?
我要感谢大家的深思熟虑和创造性的回应.在所有这些来回之后,看起来这个问题的真正答案是"等到.NET 4.0." 我将向Noldorin提供奖励,以提供仍然利用LINQ的最实用的答案,特别提到Jacob Proffitt提出的使用实体框架的响应,而无需在数据库端进行修改.还有其他很好的答案,如果你是第一次看到这个问题,我强烈建议你阅读所有已被投票的人,以及他们的评论.这确实是StackOverflow功能的极好例子.谢谢你们!
Nol*_*rin 40
您应该能够使用对AsEnumerable扩展方法的调用来强制查询使用LINQ to Objects而不是LINQ to Entities进行分组.
请尝试以下方法:
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)
};
Run Code Online (Sandbox Code Playgroud)
这至少意味着该where子句由LINQ to Entities执行,但该group子句对于实体来说太复杂了,它由LINQ to Objects完成.
如果你对此有任何好运,请告诉我.
这是另一个建议,它可能允许您使用LINQ to Entities来完成整个事情.
(t.TargetDate.Days - firstDay.Days) / 7
Run Code Online (Sandbox Code Playgroud)
这只是扩展了操作,因此只执行整数减法而不是DateTime减法.
它目前尚未经过测试,因此它可能有效也可能无效......
只要您使用SQLServer,您也可以在LINQ中使用SQL函数:
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();
Run Code Online (Sandbox Code Playgroud)
此示例改编自MVP Zeeshan Hirani在此主题: MSDN
| 归档时间: |
|
| 查看次数: |
30379 次 |
| 最近记录: |