LINQ – stream利和查询expression式 – 有没有比其他的好处?
自从generics以来,LINQ是对.NET最大的改进之一,它节省了大量的时间和代码。 然而,stream畅的语法似乎比查询expression式语法更加自然。
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();
两者之间有什么区别,还是比其他人有什么特别的好处呢?
也不是更好:他们服务于不同的需求。 当您想要利用多个范围variables时,查询语法就会自动生成。 这发生在三种情况下:
- 使用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 };
当我可以用这种方式编写整个expression式时,我更喜欢使用后者(有时称为“查询理解语法”)。
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();
我发现有点容易阅读。
每种风格都有其优点和缺点。 查询语法对于连接来说更好,它有一个有用的let关键字,使查询内的临时variables变得容易。
另一方面,stream利的语法有更多的方法和操作不通过查询语法公开。 另外,因为他们只是扩展方法,你可以写自己的。
我发现每次我开始用查询语法编写一个LINQ语句,我最终不得不把它放在括号中,并回到使用stream利的LINQ扩展方法。 查询语法本身没有足够的function来使用。
在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
VB.NET的查询语法也比C#中的function更强大,更简洁: 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);
我没有得到查询语法。 我脑子里没有任何理由。 让我们可以用.Select和匿名types来实现。 我只是觉得在那里用“标点符号”看起来更有组织性。
stream畅的界面,如果只是一个地方。 如果我需要select或orderby,我通常使用查询语法。
stream利的语法确实看起来更强大,它也应该更好地将代码组织成小的可重用的方法。
我知道这个问题是用C#标记的,但是Fluent语法在VB.NET中是非常详细的。
我真的很喜欢Fluent的语法,我尽量使用它,但是在某些情况下,例如在使用连接的地方,我通常更喜欢Query语法,在这种情况下,我觉得更容易阅读,而且我认为有些人Query(SQL-like)语法比lambdas更为熟悉。
虽然我理解并喜欢stream畅的格式,但由于可读性的原因,我暂时坚持查询。 刚刚被介绍给LINQ的人会发现查询阅读起来更舒适。
我更喜欢查询语法,因为我使用SQL来自传统的Web编程。 我的脑袋变得容易多了。 但是,它认为我会开始利用.Where(lambda),因为它肯定要短得多。
我一直在使用Linq大概6个月。 当我第一次使用它时,我更喜欢查询语法,因为它与T-SQL非常相似。
但是,现在我正在逐渐接近前者,因为很容易将可重用的代码块编写为扩展方法,并将它们链接在一起。 虽然我确实发现把每个子句放在自己的路线上,可以提高可读性。
我刚刚build立了我们公司的标准,并强制使用扩展方法。 我认为这是一个好主意,select一个在另一个,不要混淆在代码中。 扩展方法阅读更像其他代码。
comprehension语法没有所有的操作符,并且在查询周围使用括号,并且在所有的操作都请求我从头开始使用扩展方法的时候添加扩展方法。
但大多数情况下只是个人喜好,有一些例外。
- 为什么C#multidimensional array不能实现IEnumerable <T>?
- WPF MVVM为什么使用ContentControl + DataTemplate Views而不是直观的XAML Window Views?
- 如何从httpclient调用获取内容正文?
- entity framework中的SqlException – 不允许新的事务,因为会话中还有其他线程正在运行
- C#获取已用内存的%
- OpenCV C ++ / Obj-C:检测一张纸/方形检测
- 即使没有空检查,使用“as”而不是cast是否有意义?
- unsigned int与size_t
- ISO C90禁止在C中使用混合声明和代码