自从泛型以来,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();


两者之间是否有区别,还是有什么特别的好处?一个之上?

评论

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

#1 楼

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


使用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 };


评论


好答案。您能告诉我更多有关“ .Select(name => new {name,fName})”的内容吗?

–抢劫犯
2010年8月10日在12:34

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

–乔·阿尔巴哈里(Joe Albahari)
2010年8月11日,下午2:41

#2 楼

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

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


我发现它更容易阅读。

#3 楼

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

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

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

评论


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

–红豌豆
16-09-20在12:46

#4 楼

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


评论


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

– nawfal
2014年6月6日17:14

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

–艾米尔
16年11月18日在10:15

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

– Tim Schmelter
16-11-18在10:22



#5 楼

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

评论


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

–罗马·斯塔科夫
2010年5月4日18:11



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

– Xan-Kun Clark-Davis
17-2-26在10:53



#6 楼

流畅的界面(如果有的话)。如果需要选择或排序,通常使用查询语法。

#7 楼

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

#8 楼

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

#9 楼

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

#10 楼

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

#11 楼

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

#12 楼

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

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

#13 楼

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

理解语法并不具有所有运算符,并且在查询周围使用括号并添加扩展方法毕竟只是乞求我从一开始就使用扩展方法。 />
但是在大​​多数情况下,这只是个人喜好,有一些例外。

评论


我不会强制个人喜好。但这就是我。

– Memet Olsen
16 Mar 23 '16 at 9:47