【问题标题】:Can this LINQ lambda expression be written any better?这个 LINQ lambda 表达式可以写得更好吗?
【发布时间】:2013-09-20 16:57:59
【问题描述】:

为了了解知识,我想将 SQL 查询转换为 LINQ 查询表达式。 这是原始 SQL:

SELECT CT.COURSE_NODE_ID AS CNID, CT.NODE_TEXT
FROM    COURSE_RELATED_VERSIONS AS CRV INNER JOIN
        COURSE_TREE AS CT ON CRV.COURSE_NODE_ID = CT.COURSE_NODE_ID
WHERE (CRV.COURSE_ID = '38890') AND (CRV.COURSE_PARENT_NODE_ID = '-1')

基本上,只需根据特定条件(键匹配、课程 ID 匹配条件、父节点不等于 -1)从表中获取两个字段。 这是我使用 LINQPad 提出的 LINQ 查询表达式:

from ct in COURSE_TREEs
join crv in COURSE_RELATED_VERSIONS 
     on ct.COURSE_NODE_ID equals crv.COURSE_NODE_ID
where crv.COURSE_ID == 38890 && crv.COURSE_PARENT_NODE_ID == -1
select new {ct.COURSE_NODE_ID, ct.NODE_TEXT}

还不错,我以 SQL 为中心的大脑仍然可以理解。但是,出于笑容,我想知道这个查询表达式作为 lambda 表达式会是什么样子。对于我的一生,我无法弄清楚语法。因此,我使用 LINQPad 中的 lambda 工具来查看我的 LINQ 查询表达式的样子。这里是:

COURSE_TREEs
.Join (
   COURSE_RELATED_VERSIONS, 
   ct => ct.COURSE_NODE_ID, 
   crv => crv.COURSE_NODE_ID, 
   (ct, crv) => 
      new  
      {
         ct = ct, 
         crv = crv
      }
)
.Where (temp0 => ((temp0.crv.COURSE_ID == 38890) && (temp0.crv.COURSE_PARENT_NODE_ID ==  -1)))
.Select (
   temp0 => 
      new  
      {
         COURSE_NODE_ID = temp0.ct.COURSE_NODE_ID, 
         NODE_TEXT = temp0.ct.NODE_TEXT
      }
)

哇!不是我认为 lambda 表达式查询的样子。所以,我正在研究 LINQPad 的输出,了解我的查询表达式如何看起来像一个 lambda 表达式,我想知道它是否可以写得更好?我仍在学习 LINQ(和 lambda 表达式)的技巧,但我不禁觉得这里生成的 lambda 表达式太复杂了!我错了吗?是否可以编写一个 lambda 表达式,它产生与原始 SQL 和查询表达式相同的输出,但又不是不必要的复杂?也许“复杂”是主观的,因为它可能只会在我的 SQL 大脑中显得复杂。我只是觉得LINQPad中生成的lambda表达式可以写得更好......我只是不知道如何。

【问题讨论】:

  • 这取决于你。但我认为codereview更适合这个问题
  • 我认为您在该查询中遇到的大多数问题都是由于变量名称和空格使用问题造成的。查询本身对我来说看起来还不错,但它可以使用一些不会改变其编译代码的方式进行相当多的重构。该特定查询(比许多查询更多)更适合查询语法样式而不是方法语法样式,因此使用它没有任何问题。对于不同类型的查询,方法语法往往看起来更简洁。
  • 您需要在查询语法中使用手动连接吗?如果可以从数据库结构中推断出关系,则 Lambda 会更清晰。
  • @sgmoore 是正确的。 LINQ 新手犯的最大错误之一是使用手动连接而不是通过关联进行查询。请参阅本文中的“协会”:linqpad.net/WhyLINQBeatsSQL.aspx

标签: c# sql linq linqpad


【解决方案1】:

编译器将原始查询中的查询理解语法转换为与 LinqPad 输出的非常相似的内容。这些是实际调用的方法。

如果您使用的是Join,这将非常简单。如果您查看JoinWhereSelect 的方法签名,您应该能够弄清楚每个部分在做什么以及为什么这样做。当你分解它时,你应该会发现它实际上并不比你原来的查询复杂,它只是被重写为使用方法调用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-22
    • 2016-04-25
    • 2014-08-23
    • 2017-06-15
    • 1970-01-01
    相关资源
    最近更新 更多