【问题标题】:Refine Enumerable LINQ WHERE statement with repeated parameters使用重复参数优化 Enumerable LINQ WHERE 语句
【发布时间】:2013-12-19 03:44:47
【问题描述】:

我有以下代码来返回在确定的日期内合同到期的所有记录:

return pSource
                .Where(q => 
                    q.StaffContracts.OrderByDescending(p => p.SignedDate).FirstOrDefault().Timespan.HasValue &&
                    q.StaffContracts.OrderByDescending(p => p.SignedDate).FirstOrDefault().SignedDate.HasValue &&
                    (q.StaffContracts.OrderByDescending(p => p.SignedDate).FirstOrDefault().SignedDate.Value.AddMonths( q.StaffContracts.OrderByDescending(p => p.SignedDate).FirstOrDefault().Timespan.Value)
                    - now).TotalDays <= value);

如您所见,q.StaffContracts.OrderByDescending(p =&gt; p.SignedDate).FirstOrDefault() 重复了很多次。有没有办法缩短这个声明?而它的等价SQL语句又是什么?

【问题讨论】:

    标签: c# sql linq


    【解决方案1】:

    这样做怎么样?

    return
        from q in pSource
        let sc = q.StaffContracts
            .OrderByDescending(p => p.SignedDate)
            .FirstOrDefault()
        where sc != null
        let ts = sc.Timespan
        let sd = sc.SignedDate
        where ts.HasValue
        where sd.HasValue
        where (sd.Value.AddMonths(ts.Value) - now).TotalDays <= value
        select q;
    

    【讨论】:

      【解决方案2】:

      你可以把它变成一个方法体。它返回bool。检查null 也可能不是一个坏主意:

      return pSource.Where(q => {
          var contract = q.StaffContracts.OrderByDescending(p => p.SignedDate).FirstOrDefault();
      
          if (contract == null)
              return false; // returns nothing
      
          return contract.Timespan.HasValue &&
                 contract.SignedDate.HasValue &&
                 (contract.SignedDate.Value.AddMonths(contract.Timespan.Value) - now)
                 .TotalDays <= value;
      });
      

      我会说这会大大提高你的表现..只有一个订单电话。

      【讨论】:

      • 谢谢,我在 lambda 操作中收到语法错误:A lambda expression with a statement body cannot be converted to an expression tree。我该如何解决这个问题?抱歉,我是 LINQ 的新手。
      • 啊。那是个问题。 LINQ 不是直接的 SQL 技术。它被 LINQ-to-SQL、实体框架、NHibernate 等 ORM 用于创建 SQL。它通过访问 lambda 表达式中的每个节点来生成 SQL 来做到这一点。我给你的是 LINQ.. 但它不是 lambda 表达式.. 它是一个完整的方法体。不幸的是,这将无法转换为 SQL。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-05
      相关资源
      最近更新 更多