我想返回一个包含与年龄分布相关的数据的列表(例如:0-9岁有10人,10-19岁有7人等)
这是我的查询:
public List<ReportHelper> GetAgeDistribution(int userId)
{
var itemList = (from item in this.ObjectContext.TreeMembers
where item.UserId == userId
group (DateTime.Now - (item.Birthdate ?? DateTime.Now)).Days/365.25
by ((DateTime.Now - (item.Birthdate ?? DateTime.Now)).Days / 365.25) / 9);
List<ReportHelper> list = new List<ReportHelper>();
foreach (var item in itemList)
list.Add(new ReportHelper { Data = item.Count(), Label = item.Key + "-" + (item.Key + 9) });
return list;
}
当我运行这个查询时,我得到dbarithmeticexpression异常:
DbArithmeticExpression arguments must have a numeric common type.
如何解决这个错误?我知道实体框架4无法将我的表达式转换为普通的旧sql。我怎样才能暗示它我要做什么呢?
提前感谢:)
Saeed是对的;最好的方法是通过 EntityFunctions.DiffYears
方法使用规范DiffYears
函数。
此外,您将年龄划分为[0 - 9]
年,[10 - 19]
年等桶的逻辑似乎不正确;你应该把整个年份除以10
,而不是9
。
这个查询应该可以正常工作:
var itemList = from item in this.ObjectContext.TreeMembers
where item.UserId == userId
let age = EntityFunctions.DiffYears
(item.Birthdate, DateTime.Now) ?? 0
group item by age / 10 into ageGroup
select new
{
AgeInCompletedDecades = ageGroup.Key,
Count = ageGroup.Count()
};
在EF中不能这样做:
DateTime.Now - (item.Birthdate ?? DateTime.Now))....
您可以使用实体规范函数来实现此目的。
事实上你不能在EF中做DateTime1 - DateTime2
。
我的猜测是将365.25更改为365(因此它是int
,如Days
属性)。
如果使用mydate.ToOADate()
函数将日期转换为数值会怎样?此函数将日期转换为双精度值,其中双精度值的整数部分表示日期,小数部分表示小数日期(即一天中的时间)。
我不太了解实体算法,但如果日期是双精度的,那么它可能不会抛出异常-只是一个猜测。