C#和VB.NET中的示例都可以。
我有一个表“People”,其中包含以下列:
-FullName(nvarchar not null) -DOB(datetime null)
我想写一个LINQ to SQL来按年龄对人进行分组,如下面的结果:
年龄19:4 ppl
年龄20:5人
21岁:6 ppl
依旧......
这是我的尝试:
Dim query = From ppl In db.People _
Select New With {.Age = DateTime.Now.Year - CDate(ppl.DOB).Year, .CountAge = ppl.Count}
请注意,表中的某些人没有DOB记录,因此不应包含这些记录。 DOB列的记录如下,这是1982-10-24 10:12:45 AM,因为它是一个DateTime列。
答案 0 :(得分:2)
更准确的解决方案:
db.People.Where(p => p.DOB != null).GroupBy(p => ((DbFunctions.DiffDays(p.DOB, DateTime.Today) / 365)))
.Select(g => new {Age=g.Key, Count = g.Count()})
分组到间隔:
var interval = 5; //years
db.People.Where(p => p.DOB != null).GroupBy(p => ((DbFunctions.DiffDays(p.DOB, DateTime.Today) / 365) / interval))
.Select(g => new {GroupIndex=g.Key, Count = g.Count()})
答案 1 :(得分:1)
如果您使用的是EF Core 3.1,则DbFunctions已替换为EF.Functions。 作为另一种选择,您可以使用以下方法:
var query = await db.People
.GroupBy(x.DateOfBirth.HasValue ? (int)(EF.Functions.DateDiffDay(x.DateOfBirth.Value, DateTime.UtcNow) / 365.25) : (int?)null)
.Select(x => new
{
Age = x.Key,
Count = x.Count(),
})
.ToListAsync(cancellationToken);
它考虑了“生日”,而不是时间,但比仅使用“生日”更准确
答案 2 :(得分:0)
From ppl In db.People
Select New With {.Age = DateTime.Now.Year - CDate(ppl.DOB).Year,
.CountAge = ppl.Count()}
Group By (DateTime.Now.Year - CDate(ppl.DOB).Year)
我认为此查询符合您的目的。
答案 3 :(得分:0)
假设DOB是可以为空的DateTime(DateTime?),那么在那里没有DOB记录意味着null:
from ppl in db.People
where ppl.DOB.HasValue
let age = DateTime.Today.Year - ppl.DOB.Value.Year
group ppl by age into ages
select new { Age=ages.Key, Persons = ages }
这是在C#中,但由于语法类似,因此应该很好地转换为VB。
答案 4 :(得分:0)
这应该有效(并且应该更准确地计算年龄):
var query = from person in db.People
where person.DOB.HasValue
let age = (DateTime.Now - username.UpdateDateTime.Value).Days % 365
group person by age into ages
select new { Age =ages.Key, People = ages.Count() }
答案 5 :(得分:0)
我宁愿:
var result = db.People
.Where(p => p.DOB != null) // exclude null DOB's from stats
.GroupBy(p => p.DOB.Value.Year)
.Select(g => new { Age = DateTime.Now.Year - g.Key, Count = g.Count() });
我们正在这里与出生年份分组。这应该转换为SQL中的GROUP BY YEAR(dob)
,与GROUP BY YEAR(GETDATE()) - YEAR(dob)
相比,这可能会有更好的性能或优化。将行表达式映射到索引几乎是不可能的,但可以优化某些结构(如YEAR()
),以部分使用日期时间索引。我在这里做了很多假设,就像datetime
结构以年开始一样,SQL服务器关心YEAR(x)
进行优化等。构建LINQ查询时要记住这种情况仍然很好。