【问题标题】:Good linq query approach to write Queries which are based on DateTime clause编写基于 DateTime 子句的查询的良好 linq 查询方法
【发布时间】:2026-01-20 05:45:02
【问题描述】:

我需要根据特定用户的关系编号从数据库中获取上个月发票。 我想出了下面的 linq 查询。

// 第一步:根据关系号和OrderByDescending子句获取Bill号
**

var query = context.Billings 

 .OrderByDescending(c => c.BillGenerationDate)
                               .Where(c => c.CAFNO == caf)
                               .Select(c => c.BillNo)
                               .FirstOrDefault();

** //第 2 步:第 1 步的结果具有由 //BillGeneration date 过滤的最后(或最高)的账单编号

var bill = (from b in context.Billings
                            where b.BillNo == query
                            select b).FirstOrDefault();

第 2 步将生成所需的完整账单信息。

其他方式:

var myresult = (from c in context.Billings
                            where c.CAFNO == caf
                            orderby c.BillGenerationDate descending
                            select c).FirstOrDefault();

我觉得上面的查询可以用更好的方式重写。寻找建议以更有效的方式重写上述查询。

谢谢!!!

【问题讨论】:

    标签: sql linq linq-to-entities


    【解决方案1】:

    由于BillGenerationDate 可以为空而更新

    您当前的查询将为您提供最后可用的帐单信息,而不是上个月的发票。要简洁地获得上个月,您可以执行以下操作。

    var invoice = context.Billings
                         .FirstOrDefault( 
                             c => c.CAFNO == caf && 
                                  (c.BillGenerationDate ?? new DateTime()).AddMonths(1).Month == DateTime.Now.Month &&
                                  (c.BillGenerationDate ?? new DateTime()).AddMonths(1).Year == DateTime.Now.Year)
    

    但是,如果您每月有超过一张发票,这并不能保证任何订单,您可以再次添加订购短语。

    var invoice = context.Billings
                         .OrderByDescending(c => c.BillGenerationDate)
                         .FirstOrDefault( 
                             c => c.CAFNO == caf && 
                                  (c.BillGenerationDate ?? new DateTime()).AddMonths(1).Month == DateTime.Now.Month &&
                                  (c.BillGenerationDate ?? new DateTime()).AddMonths(1).Year == DateTime.Now.Year)
    

    注意:这与您上面的第二个查询(除了额外的月份过滤器)没有任何不同,因为 FirstOrDefault(Func<T,Bool) 重载就像组合的 Where(Func<T,Bool>).FirstOrDefault() 一样,因此您可以选择哪个更具可读性。

    【讨论】:

    • 嗨 user1793607,我在 .FirstOrDefault 处收到错误“模糊调用”,并且无法将运算符“+”应用于 System.Nullable 类型的操作数和 c.BillGenerationDate +1
    • @coddey 第二个是确保你在两个日期都得到.Month,因为听起来好像缺少一个,这应该有望解决第一个问题(因为类型推断应该很好形成)
    • @coddey 如果您的BillGenerationDate 可以为空,那么您需要提供一个默认值来检查...