流畅和查询表达-其中一个比另一个有任何好处吗?

LINQ是。net自泛型以来最大的改进之一,它为我节省了大量的时间和代码。然而,对我来说,流畅的语法似乎比查询表达式语法更自然。

var title = entries.Where(e => e.Approved)
.OrderBy(e => e.Rating).Select(e => e.Title)
.FirstOrDefault();


var query = (from e in entries
where e.Approved
orderby e.Rating
select e.Title).FirstOrDefault();

两者之间有什么区别吗?或者两者之间有什么特别的好处吗?

74036 次浏览

流畅的语法确实看起来更强大,它也应该更好地将代码组织成小的可重用方法。

流畅的界面,如果只有一个位置的话。如果我需要选择或排序,我通常使用Query语法。

我真的很喜欢Fluent语法,我尽可能地使用它,但在某些情况下,例如我使用连接时,我通常更喜欢Query语法,在这些情况下,我发现它更容易阅读,而且我认为有些人更熟悉Query(类似sql)语法,而不是lambdas。

虽然我确实理解并喜欢流畅的格式,但出于可读性的原因,我暂时坚持使用Query。刚接触LINQ的人会发现Query读起来要舒服得多。

每种风格都有其优点和缺点。当涉及到连接时,查询语法更好,并且它有有用的关键字,可以轻松地在查询中创建临时变量。

另一方面,流畅的语法有很多不通过查询语法公开的方法和操作。此外,由于它们只是扩展方法,您可以编写自己的扩展方法。

我发现,每当我开始使用查询语法编写LINQ语句时,我最终不得不把它放在括号中,然后回到使用流畅的LINQ扩展方法。查询语法本身没有足够的特性。

当我可以用这种方式编写整个表达式时,我更喜欢使用后者(有时称为“查询理解语法”)。

var titlesQuery = from e in entries
where e.Approved
orderby e.Rating
select e.Titles;


var title = titlesQuery.FirstOrDefault();

只要我必须添加(括号)和.MethodCalls(),我改变。

当我使用前者时,我通常每行放一个子句,像这样:

var title = entries
.Where (e => e.Approved)
.OrderBy (e => e.Rating)
.Select (e => e.Title)
.FirstOrDefault();

我觉得这样更容易理解。

我更喜欢查询语法,因为我来自使用SQL的传统web编程。这对我来说更容易理解。然而,它认为我将开始使用. where (lambda),因为它肯定更短。

我完全不懂查询语法。在我看来,没有理由这么做。let可以通过. select和匿名类型来实现。我只是觉得在里面加上标点符号看起来更有条理。

我已经使用Linq 6个月了。当我第一次开始使用它时,我更喜欢查询语法,因为它非常类似于T-SQL。

但是,我现在逐渐转向前者,因为将可重用代码块编写为扩展方法并将它们链接在一起很容易。虽然我确实发现把每个子句放在单独的行上对可读性有很大帮助。

两者都不好:它们满足不同的需求。当你想利用多个范围变量时,查询语法就会发挥作用。这种情况有三种:

  • 当使用let关键字时
  • 当你有多个生成器时(子句)
  • 当进行连接时

下面是一个例子(来自LINQPad示例):

string[] fullNames = { "Anne Williams", "John Fred Smith", "Sue Green" };


var query =
from fullName in fullNames
from name in fullName.Split()
orderby fullName, name
select name + " came from " + fullName;

现在将其与方法语法中的相同内容进行比较:

var query = fullNames
.SelectMany (fName => fName.Split().Select (name => new { name, fName } ))
.OrderBy (x => x.fName)
.ThenBy  (x => x.name)
.Select  (x => x.name + " came from " + x.fName);

另一方面,方法语法公开了查询操作符的全部范围,并且使用简单查询更加简洁。您可以通过混合查询和方法语法来获得两者的优点。这通常在LINQ to SQL查询中完成:

var query =
from c in db.Customers
let totalSpend = c.Purchases.Sum (p => p.Price)    // Method syntax here
where totalSpend > 1000
from p in c.Purchases
select new { p.Description, totalSpend, c.Address.State };

我知道这个问题是用c#标记的,但是VB.NET的Fluent语法非常冗长。

我刚刚建立了我们公司的标准,我们强制使用扩展方法。我认为在代码中选择一个而不是另一个是一个好主意,不要把它们混在一起。扩展方法读起来更像其他代码。

理解语法并没有所有的操作符,在查询周围使用圆括号和添加扩展方法只是在恳求我从一开始就使用扩展方法。

但在大多数情况下,这只是个人喜好,只有少数例外。

VB。网中,我非常喜欢查询语法。

我讨厌重复这个丑陋的__abc0关键字:

Dim fullNames = { "Anne Williams", "John Fred Smith", "Sue Green" };
Dim query =
fullNames.SelectMany(Function(fName) fName.Split().
Select(Function(Name) New With {Name, fName})).
OrderBy(Function(x) x.fName).
ThenBy(Function(x) x.Name).
Select(Function(x) x.Name & " came from " & x.fName)

在我看来,这个简洁的查询更具可读性和可维护性:

query = From fullName In fullNames
From name In fullName.Split()
Order By fullName, name
Select name & " came from " & fullName

VB。NET的查询语法也比c#: https://stackoverflow.com/a/6515130/284240更强大,更简洁

例如,这个LINQ到数据集(对象)查询

VB。NET:

Dim first10Rows = From r In dataTable1 Take 10

c#:

var first10Rows = (from r in dataTable1.AsEnumerable()
select r)
.Take(10);

微软的文件如下:

作为一个规则,当你编写LINQ查询,我们建议您尽可能使用查询语法,必要时使用方法语法。在两种不同的形式之间没有语义或性能上的差异。查询表达式通常比用方法语法编写的等效表达式更具可读性。

https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/#query-expression-overview

他们还说:

要开始使用LINQ,你不需要大量使用lambdas。但是,某些查询只能用方法语法表示,其中一些查询需要lambda表达式

https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/query-syntax-and-method-syntax-in-linq