Linq表达式语法-如何使其更具可读性?
我正在编写一些东西,将使用Linq通过Linq2Sql和内存中的对象列表组合来自数据库的结果,以找出哪些内存中的对象与数据库中的某个对象匹配 我提出了表达式和查询语法的查询 表达式语法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
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:说真的,别担心;我真的没有那么强烈的感觉。你是对的,它没有提供更多,我只是(温和地)觉得另一个副本是要删除的。由于我的得票率为零,现在取消投票没有什么好处。让我们删除这些评论,忘掉它——更好的问题需要回答:)