LINQ查询表达式和扩展方法有什么区别下面是两个返回相同数据的查询。除了风格,我不确定哪个更好。哪些因素会影响这些查询?使用一种样式比使用另一种样式有什么好处?示例1varx=fromsindb.Surveysjoinsqindb.Survey_Questionsons.ID等于sq.Survey_IDjoinqindb.Questionsonsq.Question_ID等于q.IDjoinqgindb.Question_Groupsonq.IDequalsqg.Question_ID其中s.Type_ID.Equals(typeID)&s.Type.Equals(type)selectnew{question=sq.Question,status=sq.Status,grp=qg};示例2varx=db.Surveys。其中(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{问题=q.question,status=q.status,group=qg}).ToList();更新:你修正了你的标题,所以忽略咆哮。您的问题标题与您的代码示例无关。您的问题暗示一种语法是IEnumerable,另一种是IQueryable,但这是不正确的。在您的示例中,如果db.Surveys是IQueryable,那么您的两个示例都使用IQueryable。我将尝试回答这两个问题。您的两个代码示例只是编写相同LINQ查询的不同方式(假设它们写得很好)。示例1中的代码只是示例2中代码的简写。编译器以相同的方式处理两个示例中的代码。想想处理int的C#编译器?与Nullable相同。C#和VB.Net语言都提供了这种简写查询语法。其他语言可能没有这个语法,必须使用示例2的语法。事实上,其他语言可能甚至不支持扩展方法或lambda表达式,你不得不使用更丑陋的语法。更新:将桑德的例子更进一步,当你写这个(查询理解语法)时:varsurveyNames=fromsindb.Surveysselects.Name你认为编译器将该缩写翻译成这个(扩展方法和lambda表达式):IQueryablesurveyNames=db.Surveys.Select(s=>s.Name);但实际上扩展方法和lambda表达式本身就是简写。编译器发出类似这样的东西(不完全是,只是为了给出一个想法):Expression>selector=delegate(Surveys){returns.Name;};IQueryablesurveyNames=Queryable.Select(db.Surveys,selector);请注意,Select()只是Queryable类中的一个静态方法。如果您的.NET语言不支持查询语法、lambda或扩展方法,那么您将不得不自己编写代码。使用一种样式比使用另一种样式有什么好处?对于小型查询,扩展方法可以更紧凑:varitems=source.Where(s=>s>5);此外,扩展方法语法可以更灵活,例如条件where子句:varitems=source.Where(s=>s>5);如果(smallerThanThen)items=items.Where(s=>s(s%2)==0);返回items.OrderBy(s=>s);此外,有几种方法只能通过扩展方法语法(Count()、Aggregate()、Take()、Skip()、ToList()、ToArray()等)使用,所以如果我要使用其中之一,我通常用这种语法编写整个查询,以避免混合两种语法。varfloridaCount=source.Count(s=>s.State=="FL");varitems=source.Where(s=>s>5).Skip(5).Take(3).ToList();else一方面,当查询变得更大和更复杂时,查询理解语法可以更清晰,尤其是当您开始使用一些let、group、join等并发症时。最后,我通常使用对每个特定查询更好的那个。更新:你修改了你的标题,所以忽略其余部分......现在,关于你的标题:关于LINQ,IEnumerable和IQueryable非常相似。它们都有几乎相同的扩展方法(Select、Where、Count等),主要(唯一?)区别在于IEnumerable将Func作为参数,而IQueryable将Expression>作为参数。你表达两种方式(通常是兰巴表达),但在内部它们是完全不同的。IEnumerable是LINQtoObjects的入口点。LINQtoObjects扩展方法可以在任何IEnumerable(数组、列表、任何可以用foreach迭代的东西)上调用,并且Func在编译时转换为IL,在运行时表现得像普通方法代码。请注意,其他一些LINQ提供程序使用IEnumerable,因此实际上在幕后使用LINQtoObjects(LINQtoXML、LINQtoDataSet)。IQueryable由LINQtoSQL、LINQtoEntities和其他需要检查查询并转换查询而不是直接执行代码的LINQ提供程序使用。IQueryable查询及其Expression>不会在编译时编译到IL中。相反,会创建一个表达式树,并且可以在运行时对其进行检查。这允许将语句翻译成其他查询语言(例如T-SQL)。表达式树可以在运行时编译为Func并在需要时执行。可以在这个问题中找到差异的示例,其中OP希望在SQLServer中执行部分LINQtoSQL查询,将对象放入托管代码中,然后在LINQtoObjects中执行其余查询。为实现这一点,他所要做的就是将IQueryable转换为IEnumerable,并且他希望发生切换。LINQ是一种技术的流行语。IQueryable是LINQ使用的.NET接口。除了风格,两者没有区别。使用任何你喜欢的风格。对于长语句(如此处所示),我更喜欢第一种样式,而对于非常短的语句,我更喜欢第二种样式。第一个示例中的where子句实际上只是第二个方法中where子句的语法糖。事实上,您可以自己编写与Linq或IQueryable无关的类,只需使用Where方法,并使用该语法糖。例如:publicclassMyClass{publicMyClassWhere(Funcpredicate){returnnewMyClass{StringProp="HelloWorld"};}publicMyClassSelect(Funcpredicate){returnnewMyClass();}公共字符串StringProp{得到;放;这显然是一个愚蠢的例子,但请注意,有一个Where方法只返回一个新的MyClass,其中stringprop设置为HelloWorld。显示:MyClassa=newMyClass();varq=frompinawherep.StringProp=="foo"//我们在这里放什么并不重要,因为我们并没有真正检查谓词selectp;Console.WriteLine(q.StringProp);这将导致写入“HelloWorld”。同样,这个例子显然毫无意义,但它证明了“where”语法只是在代码中寻找一个带有Func的Where方法。查询表达式和扩展方法是两种相同的方法。查询表达式在编译时转换为扩展方法——对于那些更熟悉SQL的人来说,它们只是语法糖。当你这样写时:varsurveyNames=fromsindb.Surveysselects.Name;编译器将它变成:IQueryablesurveyNames=db.Surveys.Select(s=>s.Name);实际上,我认为查询表达公式只是出于营销原因而创建的-一种类似SQL的语言结构,在开发LINQ时用作万能的,而不是真正有用的东西。我发现大多数人只是直接使用扩展方法,因为它们会导致更统一的编码风格,而不是混合使用C#和SQL。1./你的问题标题和你问的不符。2./你的问题标题真的没有意义。Linq代表语言集成查询,是一组技术和实践的总称,而IQueryable是一个常用于促进Linq的接口。您正在比较苹果和橘子3./关于您的实际问题,主要区别在于风格,对于像这样的复杂查询,我个人的偏好是版本2,因为它清楚地显示了结果集的进度。你的Sample1是Linq的顶层表示,可读性更强,编译时会转为表达式树,也就是你的Sample2。varx=fromsindb.Surveysjoinsqindb.Survey_Questionsons.ID等于sq.Survey_IDjoinqindb.Questionsonsq.Question_ID等于q.IDjoinqgindb.Question_Groupsonq.ID等于qg。Question_IDwheres.Type_ID.Equals(typeID)&s.Type.Equals(type)selectnew{question=sq.Question,status=sq.Status,grp=qg};可以试试下面的代码来获取写好的查询表达式varexp=x.Expression;当查询不太复杂时使用表达式我认为您的问题更像是这样,“IEnumerable和IQueryable与LINQ有什么区别”LINQ查询默认返回IQueryable。IQueryable允许您在执行查询之前将额外的过滤器或“子句”附加到查询。您的LINQ查询(第一个示例)和使用方法链的LINQ(第二个示例)使用不同的语法来产生相同的结果。LINQ查询可以写成LINQ方法链,反之亦然。这取决于您的喜好。@Lucas:不同之处在于IEnumerable进行内存中查询,而IQueryable进行内存外查询。这意味着一旦您进入foreach迭代器,您就在使用IEnumerable,而当您构建查询时,通过扩展方法使用LINQ或从对象语法中的o,您正在构建一个IQueryable。每当触摸枚举器时,都会执行IQueryable。另一点值得一提的是,Linq扩展方法遵循C#语言,而查询理解的东西是预编译的,就像内置在编译器中一样。也就是可以导航到.Select(x=>的定义处而不能from...where...select大家有用,需要多了解C#学习教程,希望大家多多关注.本文收集自网络,不代表立场,如涉及侵权,请点右联系管理员删除,如需转载请注明出处:
