旧 ADO.NET 查询的 LINQ 查询

LINQ Query for an old ADO.NET Query

提问人:hillcountry99 提问时间:11/15/2023 更新时间:11/15/2023 访问量:73

问:

我不习惯使用 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
C# 实体框架 LINQ-to-SQL

评论

0赞 Flydog57 11/15/2023
请考虑使用查询推导语法 (, etc)。与函数语法相比,该 synax 的 Join 语法更容易理解。否则,您需要知道 Stackoverflow 不是一个“我有问题,为我编写一些代码”的网站。你应该试着弄清楚如何做你想做的事情,试着去做,然后,如果你有问题,回来问一个 Stackoverflow 问题from p in patients
0赞 topsail 11/15/2023
另外,不要试图一次写完......从患者和患者标准开始。完成后,将计费设置添加到查询中。完成后,添加用户 ID ...因此,就像常规 SQL 一样,一次构建一个查询。
0赞 Svyatoslav Danyliv 11/15/2023
查询很简单,ChatGPT 应该可以轻松翻译它。
1赞 Svyatoslav Danyliv 11/15/2023
@PanagiotisKanavos,不要告诉我您从不使用 LINQ 联接;)
1赞 Svyatoslav Danyliv 11/15/2023
@PanagiotisKanavos,当我需要临时查询时,我使用 LINQ vial ,当我运行 ETL 作业时,我再次使用 LINQ。编写 SQL 变得过于无聊和冗长。linq2dblinq2db

答:

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 查询可能如下所示:UserBillingSetting

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.BillingSettingsPatient.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
                                   });