请求帮助将ADO.NET SQL查询转换为LINQ Lambda语法
将SQL查询转换为LINQ Lambda语法
原SQL查询
SELECT p.id, p.code, u.email, b.date FROM Patients p LEFT JOIN Users u ON u.patientid =p.id and u.id=p.primarycontactid INNER JOIN BillingSettings b ON b.PracticeId = p.id and b.isDue=1 WHERE p.status=1 AND p.appointmentdate > now() and p.appointmentdate < now() + 90 and b.expirationdate < now() order by p.id
转换后的LINQ Lambda代码
var now = DateTime.Now; var result = db.Patients // 过滤Patients的基础条件 .Where(p => p.Status == 1 && p.AppointmentDate > now && p.AppointmentDate < now.AddDays(90)) // 内联BillingSettings,先过滤BillingSettings的条件再关联 .Join(db.BillingSettings.Where(b => b.IsDue == 1 && b.ExpirationDate < now), patient => patient.Id, billing => billing.PracticeId, (patient, billing) => new { Patient = patient, Billing = billing }) // 左联Users,匹配双条件:u.patientid=p.id 且 u.id=p.primarycontactid .GroupJoin(db.Users, pb => new { PatientId = pb.Patient.Id, PrimaryContactId = pb.Patient.PrimaryContactId }, user => new { PatientId = user.PatientId, PrimaryContactId = user.Id }, (pb, users) => new { pb.Patient, pb.Billing, User = users.FirstOrDefault() }) // 提取需要的字段 .Select(x => new { Id = x.Patient.Id, Code = x.Patient.Code, Email = x.User?.Email, // 左联可能为null,用空传播运算符 Date = x.Billing.Date }) // 按Id排序 .OrderBy(x => x.Id) .ToList();
关键逻辑说明
- INNER JOIN 处理:先对
BillingSettings过滤IsDue=1和ExpirationDate<当前时间,再与Patients关联,和SQL中的INNER JOIN条件完全对应。 - LEFT JOIN 处理:使用
GroupJoin实现左连接,通过匿名对象匹配双关联条件,最后用FirstOrDefault()获取唯一匹配的用户(无匹配则为null),对应SQL的LEFT JOIN逻辑。 - 条件过滤:提前在数据源上过滤条件,避免后续关联后再过滤,提升查询效率。
- 投影与排序:通过
Select映射需要的字段,OrderBy实现按Id排序,和SQL输出一致。
内容的提问来源于stack exchange,提问作者hillcountry99
相关产品推荐
相关产品推荐

