What is the difference between LINQ query expressions and extension methods
下面是返回相同数据的两个查询。我不知道哪种款式更好。
哪些因素影响这些查询?使用一种样式比使用另一种样式有什么好处?
样品1
1 2 3 4 5 6 | var x = from s in db.Surveys join sq in db.Survey_Questions on s.ID equals sq.Survey_ID join q in db.Questions on sq.Question_ID equals q.ID join qg in db.Question_Groups on q.ID equals qg.Question_ID where s.Type_ID.Equals(typeID) & s.Type.Equals(type) select new { question = sq.Question, status = sq.Status, grp = qg }; |
样品2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | var x = db.Surveys.Where(s => s.Type_ID.Equals(typeID) & s.Type.Equals(type)) .Join(db.Survey_Questions, s => s.ID, sq => sq.Survey_ID, (s, sq) => new { question = sq.Question, status = sq.Status }) .Join(db.Question_Groups, q => q.question.ID, qg => qg.Question_ID, (q, qg) => new { question = q.question, status = q.status, group = qg }).ToList(); |
号
更新:你已经修改了你的标题,所以不要理会咆哮。好的。
问题的标题与代码示例无关。您的问题意味着一种语法是IEnumerable,另一种是IQueryable,但这是不正确的。在您的样本中,如果
您的两个代码示例只是编写相同LINQ查询的不同方法(假设它们编写得很好)。示例1中的代码只是示例2中代码的简写。编译器对两个示例中的代码的处理方式相同。想想C编译器对待
更新:好的。
为了进一步了解Sander的例子,当您编写这个(查询理解语法)时:好的。
1 | var surveyNames = from s in db.Surveys select s.Name |
您认为编译器会将该速记转换为以下内容(扩展方法和lambda表达式):好的。
1 | IQueryable<string> surveryNames = db.Surveys.Select(s => s.Name); |
号
但实际上扩展方法和lambda表达式本身就是简写的。编译器发出类似这样的信息(不完全是,只是为了给出一个想法):好的。
1 2 | Expression<Func<Survey, string>> selector = delegate(Survey s) { return s.Name; }; IQueryable<string> surveryNames = Queryable.Select(db.Surveys, selector); |
注意,
What are the benefits of using one style over the other?
Ok.
号
对于小型查询,扩展方法可以更紧凑:好的。
1 | var items = source.Where(s => s > 5); |
。
此外,扩展方法语法可以更灵活,例如条件WHERE子句:好的。
1 2 3 4 5 6 7 8 | var items = source.Where(s => s > 5); if(smallerThanThen) items = items.Where(s => s < 10); if(even) items = items.Where(s => (s % 2) == 0); return items.OrderBy(s => s); |
另外,一些方法只能通过扩展方法语法(count()、aggregate()、take()、skip()、tolist()、toarray()等)来使用,所以如果我要使用其中一种方法,我通常会用这种语法编写整个查询,以避免混淆这两种语法。好的。
1 2 3 4 5 6 7 | var floridaCount = source.Count(s => s.State =="FL"); var items = source .Where(s => s > 5) .Skip(5) .Take(3) .ToList(); |
。
另一方面,当一个查询变得越来越大、越来越复杂时,查询理解语法会更清晰,特别是当您开始使用一些
最后,对于每个特定的查询,我通常使用哪个更好。好的。
更新:你修改了标题,所以忽略其余的…好的。
现在,关于您的标题:关于LINQ,IEnumerable和iqueryable非常相似。它们都有几乎相同的扩展方法(select、where、count等),其中main(仅适用于?)区别在于,IEnumerable以
IEnumerable是Linq到对象的入口。可以在任何IEnumerable(数组、列表、可以与
IQueryable由Linq to SQL、Linq to Entities和其他Linq提供程序使用,这些提供程序需要检查并翻译查询,而不是直接执行代码。IQueryable查询及其 在这个问题中可以找到一个示例,说明了这一区别,其中操作人员希望在SQL Server中执行部分LINQ to SQL查询,将对象引入托管代码,并在LINQ to对象中执行其余查询。为了实现这一点,他所要做的就是将iqueryable强制转换成一个IEnumerable,在那里他希望转换发生。好的。好啊。 Linq是技术的流行语。 IQueryable是Linq使用的.NET接口。 除了风格,两者没有区别。使用你喜欢的风格。 我喜欢长句的第一种风格(如这里所示),而短句的第二种风格。
查询表达式和扩展方法是执行完全相同操作的两种方法。在编译时,查询表达式被转换为扩展方法——对于那些更熟悉SQL的人来说,它们只是语法上的糖分。
当你写这封信时:
1 | var surveyNames = from s in db.Surveys select s.Name; |
编译器将其转换为:
1 | IQueryable<string> surveryNames = db.Surveys.Select(s => s.Name); |
。
实际上,我认为查询表达式的创建只是出于市场营销的原因——一种类似SQL的语言构造,在开发Linq时起到吸引眼球的作用,而不是提供大量实际使用的功能。我发现大多数人只是直接使用扩展方法,因为它们会导致更统一的编码风格,而不是混合使用C和SQL。
第一个例子中的WHERE子句实际上只是第二个方法中WHERE子句的语法结构。事实上,您可以编写自己的类,它与Linq或IQueryable无关,您只需使用一个where方法,就可以使用这种语法糖分。例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
这显然是一个愚蠢的例子,但请注意有一个where方法,它只返回一个新的myClass,其中StringProp设置为hello world。演示:
1 2 3 4 5 | MyClass a = new MyClass(); var q = from p in a where p.StringProp =="foo" // doesnt matter what we put here, as we're not really checking the predicate select p; Console.WriteLine(q.StringProp); |
号
这将导致写出"你好世界"。同样,这个例子显然是毫无意义的,但是它证明了"where"语法只在代码中寻找一个接受func的where方法。
您的sample1是linq的顶级表示,它更具可读性,编译时将转换为表达式树,即sample2。
1 2 3 4 5 6 | var x = from s in db.Surveys join sq in db.Survey_Questions on s.ID equals sq.Survey_ID join q in db.Questions on sq.Question_ID equals q.ID join qg in db.Question_Groups on q.ID equals qg.Question_ID where s.Type_ID.Equals(typeID) & s.Type.Equals(type) select new { question = sq.Question, status = sq.Status, grp = qg }; |
您可以尝试在下面的代码中获取用于书面查询的表达式
1 | var exp=x.Expression; |
。
当查询不太复杂时使用表达式
1./您的问题标题与您的要求不匹配。2./你的问题标题没有真正意义。Linq代表语言集成查询,是一个伞形术语,用于各种技术和实践,iQueryable是一个常用于促进Linq的接口。你在比较苹果和桔子3./关于您的实际问题,主要的区别是样式,对于像这样的复杂查询,我个人的偏好是第二个版本,因为它清楚地显示了结果集的进度。
另一点值得一提的是,LINQ扩展方法坚持使用C语言,而查询理解功能是预处理的,就像编译程序中内置的一样。也就是说,您可以导航到的定义。选择(x=>但是你不能为
我认为你的问题用这样的措辞比较好,"关于LINQ,IEnumerable
默认情况下,LINQ查询返回IQueryable
您的LINQ查询(第一个示例)和使用方法链接的LINQ(第二个示例)使用不同的语法生成相同的结果。
可以将LINQ查询编写为LINQ方法链,反之亦然。这取决于你的喜好。
@卢卡斯:不同的是IEnumerable