Все, что вам нужно сделать, чтобы исправить ошибку, это поставить await
перед db.Patient.ToListAsync()
. Однако было бы лучше даже не делать этого ToList
, чтобы объединение могло быть выполнено в БД. Также обратите внимание, что вам не нужна проверка null
, так как результаты никогда не будут null
(возможно, пустыми или, возможно, будет выдано исключение, но они никогда не должны быть нулевыми)
var dobs = await (from u in db.Patient
join a in db.Analys on u.PatientId equals a.PatientId
where a.Status == Active
select u.DOB).ToListAsync();
var data = dobs
.GroupBy(x => CalculateAge(x.toString())
.Select(grp => new
{
Age = grp.Key,
Amount = grp.Count(),
})
.ToList();
dgvResult.DataSource = data;
Это будет выполните объединение и фильтрацию состояния, выберите DOB в базе данных и получите их асинхронно. Затем вы можете создать группу в памяти, поскольку CalculateAge
не может быть переведено в SQL. Но еще лучшей идеей является вычисление возраста в БД.
var now = DateTime.UtcNow(); // or .Now() if you don't store UTC in the DB
var result = from u in db.Patient
join a in db.Analys on u.PatientId equals a.PatientId
where a.Status == Active
let age = now.Year - u.DOB.Year -
((u.DOB.Month < now.Month ||
(u.DOB.Month == now.Month && u.DOB.Day < now.Day))
? 1 : 0)
group u by age into g
select new
{
Age = g.Key,
Amount = g.Count(),
};
dgvResult.DataSource = await result.ToListAsync();
Это определяет возраст путем вычитания года DOB из текущего года и затем вычитания 1, если текущий день предшествует месяцу, и Day of DOB.
Также, если вы планируете использовать CalculateAge
, просто передайте ему DateTime
вместо форматирования в string
, а затем проанализируйте его обратно в DateTime
. Вы можете передать DateTime?
, если возможно, что это может быть null
.
private int CalculateAge(DateTime? birthday)
{
int age;
if (!birthday.HasValue) return 0;
DateTime today = DateTime.Today;
age = today.Year - birthday.Value.Year;
if (birthday.Value > today.AddYears(-age))
age--;
return age;
}