流利和查询表达-相对于其他有什么好处吗?


255

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();

两者之间是否有任何区别,或者两者之间有什么特别的好处?


1
对于复杂的查询,我发现lambda语法更易于理解/阅读,但查询语法只是更漂亮。
nawfal

Answers:


255

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

  • 使用let关键字时
  • 当您有多个生成器(from子句)时
  • 加入时

这是一个示例(来自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 };

2
好答案。您可以告诉我更多有关“ .Select(name => new {name,fName})”的信息吗?
quillbreaker 2010年

12
它以匿名类型选择单个单词(anne,williams,john等)以及全名。这样,您就可以“携带”原始全名,以便在其余查询中可以访问全名和单个单词。
2010年

58

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

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();

我发现这更容易阅读。


29

每种风格各有利弊。当涉及到连接时,查询语法会更好,它具有有用的let关键字,使在查询内部创建临时变量变得容易。

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

我发现,每当我开始使用查询语法编写LINQ语句时,我最终都不得不将其放在括号中,而退回到使用流畅的LINQ扩展方法。查询语法本身没有足够的功能来使用。


“因为它们只是扩展方法,所以您可以编写自己的扩展方法。” -您会遇到这个问题吗? stackoverflow.com/a/3850254/1175496
红豌豆

20

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

我讨厌重复难看的Function关键字:

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

与C#相比,VB.NET的查询语法也更强大,更冗长:https : //stackoverflow.com/a/6515130/284240

例如,此LINQ to DataSet(Objects)查询

VB.NET:

Dim first10Rows = From r In dataTable1 Take 10

C#:

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

9
我对那些不能使用查询样式的VB开发人员表示同情。
nawfal 2014年

1
您上一个C#示例过于简单,以至于没有价值:您只需编写`dataTable1.AsEnumerable()。Take(10);即可。
Emyr

@Emyr:我的最后一段以“ VB.NET的查询语法比C#更强大,更冗长”开头,只是将VB.NET的查询语法与C#进行了比较,您正在使用方法语法。
蒂姆·施密特

15

我根本没有查询语法。我脑子里没有理由。let可以通过.Select和匿名类型实现。我只是认为其中带有“标点符号”的事物看起来更有条理。


9
流利的语法可以使多个连接很快变得很费力。我通常会使用流利的我自己-除非涉及联接。
罗曼·斯塔科夫

1
@Instance Hunter:在这里也一样。我花了相当长的时间才开始理解流利的语法。结合强大的可枚举功能和“纯”功能的概念,我现在非常喜欢它,以及以前棘手的情况,这些情况没有很好的代码表示。对于大脑的一部分,拥有查询语法仍然是一种幸运。
Xan-Kun Clark-Davis

13

流畅的界面(如果只有一个地方)。如果需要选择或排序,则通常使用查询语法。


8

流利的语法确实确实更强大,但它也可以更好地将代码组织为可重用的小型方法。


5

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


4

我真的很喜欢Fluent语法,我会尽量使用它,但是在某些情况下,例如在使用连接的地方,我通常更喜欢Query语法,在这种情况下,我觉得它更易于阅读,而且我认为有些人与lambdas相比,Query(类似于SQL)语法更熟悉。


4

虽然我确实理解并喜欢流畅的格式,但出于可读性原因,我暂时还是坚持使用Query。刚被LINQ介绍的人会发现Query更易于阅读。


4

我更喜欢查询语法,因为我来自使用SQL的传统Web编程。对我来说,缠头要容易得多。但是,它认为我将开始使用.Where(lambda),因为它肯定要短得多。


4

我已经使用Linq大约6个月了。刚开始使用它时,我更喜欢查询语法,因为它与T-SQL非常相似。

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


3

我刚刚建立了我们公司的标准,并且我们强制使用扩展方法。我认为最好选择一个而不将其混入代码中。扩展方法阅读更多类似其他代码。

理解语法没有所有运算符,并在查询周围使用括号并添加扩展方法,毕竟只是乞求我从一开始就使用扩展方法。

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


3
我不会强加个人喜好。但这就是我。
Memet Olsen
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.