我有两个表:Patient和PatientVisits。患者可以进行多次探访。 C#中有相应的Model类。
我如何编写Linq查询以获取每个患者及其最近的就诊日期?
执行此操作的原始SQL是:
select max(p."FirstName"), max(p."LastName"), max(pv."VisitDate")
from "Patients" p
left outer join "PatientVisits" pv ON pv."PatientID" = p."ID"
group by p."ID"
答案 0 :(得分:2)
var answer = (from p in context.Patients
join v in context.PatientVisits on p.ID equals v.PatientID into subs
from sub in subs.DefaultIfEmpty()
group sub by new { p.ID, p.FirstName, p.LastName } into gr
select new
{
gr.Key.FirstName,
gr.Key.LastName,
VisitDate = gr.Max(x => x == null ? null : (DateTime?)x.VisitDate)
}).ToList();
答案 1 :(得分:1)
您可以这样写Linq
from p in Patients
join pv in PatientVisits on p.PatientID equals pv.id into jointable
from z in jointable.DefaultIfEmpty()
select new
{
p.FirstName,
p.LastName,
pv.VisitDate,
};
答案 2 :(得分:0)
我的建议是:
public class Patient
{
public int PatientId { get; set; }
public string Name { get; set; }
}
public class PatientVisit
{
public Patient Patient { get; set; }
public DateTime VisitDate { get; set; }
}
class Program
{
static void Main(string[] args)
{
Patient p1 = new Patient();
p1.PatientId = 1;
p1.Name = "Harry";
Patient p2 = new Patient();
p2.PatientId = 2;
p2.Name = "John";
List<PatientVisit> visits = new List<PatientVisit>();
visits.Add(new PatientVisit
{
Patient = p1,
VisitDate = DateTime.Now.AddDays(-5)
});
visits.Add(new PatientVisit
{
Patient = p1,
VisitDate = DateTime.Now
});
visits.Add(new PatientVisit
{
Patient = p2,
VisitDate = DateTime.Now.AddDays(-1)
});
var q = (from t in visits
select new
{
t.Patient.Name,
t.Patient.PatientId,
t.VisitDate
}).OrderByDescending(t=>t.VisitDate).GroupBy(x => new { x.PatientId });
foreach (var item in q)
{
Console.WriteLine(item.FirstOrDefault().Name + ", " + item.FirstOrDefault().VisitDate);
}
}
}
答案 3 :(得分:0)
如果您的类定义具有虚拟ICollection,则可以使用它们:
public class Patient
{
public int Id { get; set; }
...
// every Patient has zero or more Visits (one-to-many)
public virtual ICollection<Visit> Visits {get; set;}
}
public class Visit
{
public int Id {get; set;}
public DateTime VisitDate { get; set; }
...
// Every Visit is done by exactly one Patient, using foreign key
public int PatiendId {get; set;}
public virtual Patient Patient { get; set; }
}
要求:给每位患者我最近的访问时间
var result = dbContext.Patients
.Where(patient => ...) // only if you don't want all Patients
.Select(patient => new
{
// Select from every Patient only the properties you plan to use
Id = patient.Id,
Name = patient.Name,
...
LastVisitTime = patient.Visits
.OrderByDescenting(visit => visit.VisitDate)
.FirstOrDefault(),
});
如果您不能使用虚拟ICollection,则必须自己进行GroupJoin:
var result = dbContext.Patients.GroupJoing(dbContext.Visits,
patient => patient.Id, // from every Patient take the Id
visit => visit.PatientId, // from every Visit take the PatientId,
(patient, visits) => new // use every patient with all his matching Visits
{ // to make a new object
Id = patiend.Id,
Name = patient.Name,
...
LastVisit = visits.OrderByDescending(visit => visit.VisitDate)
.FirstOrDefault(),
});