Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linq表达式语法-如何使其更具可读性?_Linq_Lambda - Fatal编程技术网

Linq表达式语法-如何使其更具可读性?

Linq表达式语法-如何使其更具可读性?,linq,lambda,Linq,Lambda,我正在编写一些东西,将使用Linq通过Linq2Sql和内存中的对象列表组合来自数据库的结果,以找出哪些内存中的对象与数据库中的某个对象匹配 我提出了表达式和查询语法的查询 表达式语法 var query = order.Items.Join(productNonCriticalityList, i => i.ProductID, p => p.ProductID, (i, p) => i); var query = from p in pro

我正在编写一些东西,将使用Linq通过Linq2Sql和内存中的对象列表组合来自数据库的结果,以找出哪些内存中的对象与数据库中的某个对象匹配

我提出了表达式和查询语法的查询

表达式语法

var query = order.Items.Join(productNonCriticalityList,
    i => i.ProductID,
    p => p.ProductID,
    (i, p) => i);
var query =
    from p in productNonCriticalityList
    join i in order.Items
        on p.ProductID equals i.ProductID
    select i;
查询语法

var query = order.Items.Join(productNonCriticalityList,
    i => i.ProductID,
    p => p.ProductID,
    (i, p) => i);
var query =
    from p in productNonCriticalityList
    join i in order.Items
        on p.ProductID equals i.ProductID
    select i;
我意识到,我们拥有表达式语法的所有代码完成优点,而且我确实使用了更多。主要是因为更容易创建可重用的过滤器代码块,这些代码块可以链接在一起形成更复杂的过滤器

但是对于join,后者对我来说似乎更具可读性,但这可能是因为我习惯于编写T-SQL


那么,我是错过了一个窍门,还是只是习惯了一个窍门?

好吧,这两种说法是等价的。因此,您可以同时使用它们,这取决于周围的代码和更具可读性的内容。在我的项目中,我决定使用哪种语法取决于这两个条件


就我个人而言,我会将表达式语法写在一行中,但这是一个品味问题。

这实际上都取决于偏好。有些人只是讨厌在代码中使用类似查询的语法。我欣赏查询语法,它是声明性的,可读性很强。正如您所说,第一个示例的可链接性非常好。我想,为了我的钱,我会一直保留它,直到我觉得我需要开始连接电话。

我以前也有同样的感觉。现在我发现查询语法更容易阅读和编写,特别是当事情变得复杂时。尽管第一次输入时让我很恼火,“let”以表达式语法无法理解的方式做了很多奇妙的事情。

我更喜欢复杂的查询语法,而简单的查询则更喜欢表达式语法

如果DBA阅读C代码以查看我们使用的SQL,他们将更容易理解和消化查询语法

举个简单的例子:
质疑

表情

var col2 = orders.OrderBy(o => o.Cost);
var col6 = orders.OrderBy(o => o.CustomerID).
          ThenByDescending(o => o.Cost);
对我来说,表达式语法在这里更容易理解


另一个例子:
质疑

表情

var col2 = orders.OrderBy(o => o.Cost);
var col6 = orders.OrderBy(o => o.CustomerID).
          ThenByDescending(o => o.Cost);
但是,如果查询是

//returns same results as above
var col5 = from o in orders
           orderby o.Cost descending
           orderby o.CustomerID
           select o;
//NOTE the ordering of the orderby's
这看起来有点混乱,因为字段的顺序不同,而且看起来有点向后


用于连接
质疑

表达方式:

var col2 = customers.Join(orders, 
    c => c.CustomerID,o => o.CustomerID, 
    (c, o) => new 
        { 
            c.CustomerID, 
            c.Name, 
            o.OrderID, 
            o.Cost 
        }
    );
我发现这个查询更好



我的总结是,考虑到手头的查询,使用任何看起来最容易、最快理解的方法。没有什么黄金法则可以使用。但是,如果有很多连接,我会使用查询语法。

我同意其他响应者的看法,您所问的确切问题只是偏好问题。就个人而言,我会根据我正在编写的特定查询中哪个更清晰来混合这两种形式

但是,如果我有一条评论,我会说查询看起来可能会加载订单中的所有项目。对于单个订单来说,一次就可以了,但如果您在大量订单中循环,则一次加载所有订单的所有项目可能会更有效(您可能希望另外按日期或客户或其他方式进行筛选)。如果这样做,您可以通过切换查询来获得更好的结果:

var productIds = (from p in productNonCriticalityList
                  orderby p.productID
                  select p.ProductID).Distinct();

var orderItems = from i in dc.OrderItems
                 where productIds.Contains(i.ProductID)
                    && // Additional filtering here.
                 select i;

乍一看,这有点倒退,但它可以避免加载所有订单项,也可以避免发送大量查询。它之所以有效,是因为在SQL中,
where productIds.Contains(…)
调用可以转换为
where i.ProductID(1,2,3,4,5)
。当然,您必须根据预期的订单项目数量和产品ID数量来判断。

我的订单。项目已经在内存中,但我知道您在说什么:)@Ruben:说真的,别担心;我真的没有那么强烈的感觉。你是对的,它没有提供更多,我只是(温和地)觉得另一个副本是要删除的。由于我的得票率为零,现在取消投票没有什么好处。让我们删除这些评论,忘掉它——更好的问题需要回答:)