我有一张如下表格
UserID UserName DateOfBirth
1 User1 1988-1-1
2 User2 1978-1-1
3 User3 1959-1-1
....
.....
我打算做的是查询类似于以下
的结果Age range Total User
16 - 25 10
26 - 35 20
36 - 45 15
46 - 55 16
56 - 65 30
> 70 40
我遇到的问题是我不知道如何将年龄范围分组如上。我只设法使用以下代码对每个用户的年龄进行分组
db.User
.Where(p => p.DateOfBirth != null)
.GroupBy(p => p.DateOfBirth.Value.Year)
.Select(g => new { Age = DateTime.Now.Year - g.Key, Count = g.Count() });
答案 0 :(得分:0)
这样的事情应该有效:
db.User.Where(p => p.DateOfBirth != null).ToList()
.Select(p => new { UserId = p.UserId, Age = DateTime.Now.Year - p.DateOfBirth.Value.Year })
.GroupBy(p => (int)((p.Age - 16) / 10))
.Select(g => new { AgeGroup = string.Format("{0} - {1}", g.Key * 10 + 16, g.Key * 10 + 25), Count = g.Count() });
顺便说一句,你不能只从当年减去出生年份来计算年龄。您必须创建一个函数来计算它。 Here you can find out how to calculate the age.
<强>更新强>
如果您想为年龄范围设置一个单独的组&#34;&gt; 65&#34;,那么你可以这样做:
db.User.Where(p => p.DateOfBirth != null).ToList()
.Select(p => new { UserId = p.UserId, Age = DateTime.Now.Year - p.DateOfBirth.Value.Year })
.GroupBy(p => p.Age > 65 ? 5 : (int)((p.Age - 16) / 10))
.Select(g => new { AgeGroup = g.Key == 5 ? "> 65" : string.Format("{0} - {1}", g.Key * 10 + 16, g.Key * 10 + 25), Count = g.Count() });
你也可以为16岁以下的年龄做同样的事情。如果它变得更复杂,我建议创建一个单独的函数来获取Age Group字符串。
答案 1 :(得分:0)
如果您想使用linq进行操作,首先需要创建一些代表在特定年龄范围内的值。如果您使用的是SQL数据库,这可能会更好地作为存储过程。
目前,您正在按照您所知的年份执行分组。您需要第二个操作来计算每个范围内的匹配。使用您当前拥有的linq查询,然后执行以下操作(假设您在此类中有Dictionary<string,int> ageRanges
,但您始终可以将其修改为在其他位置使用):
var query = /*LINQ QUERY HERE*/;
foreach(var g in query)
{
int ranges = g.Age / 5; //range in example is every 10 years starting at 16
switch(ranges)
{
case 0: //0 -5
case 1: //5 - 9
case 2: //10-15
continue; //we don't care about these values
case 3: //16-20
case 4: //21-25
addToRanges("16-25",g.Count);
break;
... //etc you get the idea
}
}
这是我们的addToRanges方法:
private void addToRanges(string key, int value)
{
if(ageRanges.ContainsKey(key))
{
ageRanges[key] += value;
}
else
{
ageRanges.Add(key, value);
}
}
还有很多其他方法可以做到这一点,但这只是一个关于如何执行此操作的简单示例。这不一定是最有效的例子。拥有执行此计算的存储过程将是执行此计算的最佳/最高效方法,但此方法至少将向您展示如何使用已放在一起的linq查询来执行此操作。
这是一个更像linq的例子:
db.User
.Where(p => p.DateOfBirth != null)
.GroupBy(p => p.DateOfBirth.Value.Year)
.Select(g =>
{
int age = DateTime.Now.Year - g.Key;
int range = (age / 5) - 3; //Assumes that everything is at least age > 15
if(range % 2 == 1)
range -= 1; //to make sure we group 10s not 5s
return new { Age = age, Count = g.Count(), Range = range }
})
.GroupBy(a => g.Range)
.Select(g => new {RangeValue = g.Range, Count = g.Count()});
现在,这将使用IEnumerable而不是字典产生类似的结果。