提问人:hillcountry99 提问时间:11/15/2023 更新时间:11/15/2023 访问量:73
旧 ADO.NET 查询的 LINQ 查询
LINQ Query for an old ADO.NET Query
问:
我不习惯使用 LINQ 编写 JOIN 语句。我正在尝试将这个旧查询转换为 LINQ Lambda 语法,并努力理解如何去做。任何帮助将不胜感激。
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
答:
3赞
mach
11/15/2023
#1
我在没有编译器的情况下写了这个,所以它可能是错误的,但通常你的答案如下。
var now = DateTime.Now();
var query =
from p in db.Patients
join u in db.Users on new { patientid = p.id, p.primarycontactid} equals { u.patientid, primarycontactid = u.id}
from u in userPatient.DefaultIfEmpty()
join b in db.BillingSettings on b.PracticeId equals p.id
where p.status == 1 &&
p.appointmentdate > now && p.appointmentdate < now.AddDays(90) &&
(b == null || (b.isDue == 1 && b.expirationdate < now))
orderby p.id
select new
{
p.id,
p.code,
email = u.email
date = b.date
};
1赞
Panagiotis Kanavos
11/15/2023
#2
LINQ 不是嵌入式 SQL,它是 ORM 的查询语言。ORM 处理的是对象,而不是表。ORM 本身 EF 将基于实体及其关系生成任何 JOIN。为了给出一个好的答案,人们需要知道实际实体是什么样子的。
假设 Patient 具有 and 属性,则 LINQ 查询可能如下所示:User
BillingSetting
var overduePatients= context.Patients
.Where(p=>p.AppointmentDate > DateTime.Today &&
p.AppointmentDate < DateTime.Today.AddDays(90) &&
p.BillingSetting.ExpiratonDate < DateTime.Today
&& p.BillingSetting.IsDue)
.Select(p=>new { p.Id,
p.Code,
p.User.Email,
p.BillingSetting.Date
});
不需要显式 JOIN。EF Core 将从 和 导航属性及其元数据生成这些属性。Patient.BillingSettings
Patient.User
生成的查询会将日期值作为参数传递,而不是特定于产品的调用,例如 或GetDate()
Now()
如果是 1-Many 关系,则意味着我们真的想要逾期账单,而不是患者。在这种情况下,查询必须从账单开始:BillingSettings
var overdueBills= context.BillingSettings
.Where(b=>b.Patient.AppointmentDate > DateTime.Today &&
b.Patient.AppointmentDate < DateTime.Today.AddDays(90) &&
b.ExpiratonDate < DateTime.Today
&& b.IsDue)
.Select(b=>new { b.Patient.Id,
b.Patient.Code,
b.Patient.User.Email,
b.Date
});
评论
from p in patients
linq2db
linq2db