联接具有一对多关系的两个表,并从多端选择最新表

我有两张桌子:患者和患者访问。一个病人可以有很多次就诊。C# 中有相应的模型类。


我如何编写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"


素胚勾勒不出你
浏览 92回答 4
4回答

慕婉清6462132

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();

斯蒂芬大帝

你可以这样写 Linqfrom p in Patientsjoin pv in PatientVisits on p.PatientID equals pv.id into jointablefrom z in jointable.DefaultIfEmpty()select new{  p.FirstName,   p.LastName,  pv.VisitDate,};

波斯汪

我的建议是:public class Patient{&nbsp; &nbsp; public int PatientId { get; set; }&nbsp; &nbsp; public string Name { get; set; }}public class PatientVisit{&nbsp; &nbsp; public Patient Patient { get; set; }&nbsp; &nbsp; public DateTime VisitDate { get; set; }}class Program{&nbsp; &nbsp; static void Main(string[] args)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; Patient p1 = new Patient();&nbsp; &nbsp; &nbsp; &nbsp; p1.PatientId = 1;&nbsp; &nbsp; &nbsp; &nbsp; p1.Name = "Harry";&nbsp; &nbsp; &nbsp; &nbsp; Patient p2 = new Patient();&nbsp; &nbsp; &nbsp; &nbsp; p2.PatientId = 2;&nbsp; &nbsp; &nbsp; &nbsp; p2.Name = "John";&nbsp; &nbsp; &nbsp; &nbsp; List<PatientVisit> visits = new List<PatientVisit>();&nbsp; &nbsp; &nbsp; &nbsp; visits.Add(new PatientVisit&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Patient = p1,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; VisitDate = DateTime.Now.AddDays(-5)&nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; &nbsp; &nbsp; visits.Add(new PatientVisit&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Patient = p1,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; VisitDate = DateTime.Now&nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; &nbsp; &nbsp; visits.Add(new PatientVisit&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Patient = p2,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; VisitDate = DateTime.Now.AddDays(-1)&nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; &nbsp; &nbsp; var q = (from t in visits&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;select new&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;t.Patient.Name,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;t.Patient.PatientId,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;t.VisitDate&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}).OrderByDescending(t=>t.VisitDate).GroupBy(x => new { x.PatientId });&nbsp; &nbsp; &nbsp; &nbsp; foreach (var item in q)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Console.WriteLine(item.FirstOrDefault().Name + ", " + item.FirstOrDefault().VisitDate);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}

扬帆大鱼

如果您的类定义具有虚拟 ICollection,则可以使用它们:public class Patient{&nbsp; &nbsp; public int Id { get; set; }&nbsp; &nbsp; ...&nbsp; &nbsp; // every Patient has zero or more Visits (one-to-many)&nbsp; &nbsp; public virtual ICollection<Visit> Visits {get; set;}}public class Visit{&nbsp; &nbsp; public int Id {get; set;}&nbsp; &nbsp; public DateTime VisitDate { get; set; }&nbsp; &nbsp; ...&nbsp; &nbsp; // Every Visit is done by exactly one Patient, using foreign key&nbsp; &nbsp; public int PatiendId {get; set;}&nbsp; &nbsp; public virtual Patient Patient { get; set; }}要求:给我每个病人他的最新就诊时间var result = dbContext.Patients&nbsp; &nbsp; .Where(patient => ...)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// only if you don't want all Patients&nbsp; &nbsp; .Select(patient => new&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; // Select from every Patient only the properties you plan to use&nbsp; &nbsp; &nbsp; &nbsp; Id = patient.Id,&nbsp; &nbsp; &nbsp; &nbsp; Name = patient.Name,&nbsp; &nbsp; &nbsp; &nbsp; ...&nbsp; &nbsp; &nbsp; &nbsp; LastVisitTime = patient.Visits&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .OrderByDescenting(visit => visit.VisitDate)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .FirstOrDefault(),&nbsp; &nbsp; });如果您无法使用虚拟 ICollections,则必须自己执行 Group Join:var result = dbContext.Patients.GroupJoing(dbContext.Visits,&nbsp; &nbsp; patient => patient.Id,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// from every Patient take the Id&nbsp; &nbsp; visit => visit.PatientId,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // from every Visit take the PatientId,&nbsp; &nbsp; (patient, visits) => new&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// use every patient with all his matching Visits&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // to make a new object&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Id = patiend.Id,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Name = patient.Name,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;...&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LastVisit = visits.OrderByDescending(visit => visit.VisitDate)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.FirstOrDefault(),&nbsp; &nbsp; });
打开App,查看更多内容
随时随地看视频慕课网APP