What is the difference between LINQ query expressions and extension methods

Below are two queries that return the same data. Another style then I am not sure which is better.

What factors influence these requests? What are the benefits of using one style over another?

Example 1

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

Sample 2

 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(); 
+12
c # linq query-expressions
Apr 28 '09 at 4:37
source share
8 answers

Update: You fixed your title, so ignore the bombast.

The name of your question has nothing to do with your code samples. Your question implies that one syntax is IEnumerable and the other is IQueryable, but this is not true. In your samples, if db.Surveys is IQueryable, then both samples use IQueryable. I will try to answer both questions.

Your two code examples are just different ways of writing the same LINQ queries (assuming they are well written). The code in example 1 is simply an abbreviation of the code in example 2. The compiler processes the code in both samples in the same way. Think about how the C # compiler will handle int? same as Nullable<System.Int32> . Both C # and VB.Net provide this short query syntax. Other languages ​​may not have this syntax, and you will have to use the syntax of sample 2. In fact, other languages ​​may not even support extension methods or lambda expressions, and you will have to use an even uglier syntax.




Update:

To take Sander's example further when you write this (query understanding syntax):

 var surveyNames = from s in db.Surveys select s.Name 

You think the compiler turns this shorthand into this (extension methods and lambda expressions):

 IQueryable<string> surveryNames = db.Surveys.Select(s => s.Name); 

But in fact, extension methods and lambda expressions are shorthand. Compilers emit something like this (not really, but just to give an idea):

 Expression<Func<Survey, string>> selector = delegate(Survey s) { return s.Name; }; IQueryable<string> surveryNames = Queryable.Select(db.Surveys, selector); 

Note that Select() is only a static method in the Queryable class. If your .NET language does not support query syntax, lambdas or extension methods, this is somehow the way you have to write code yourself.




What are the benefits of using one style over another?

For small queries, extension methods may be more compact:

 var items = source.Where(s => s > 5); 

In addition, the syntax of the extension method can be more flexible, for example conditional, if the sentences:

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

In addition, several methods are available only through the syntax of the extension method (Count (), Aggregate (), Take (), Skip (), ToList (), ToArray (), etc.), so if I use one of Of these, I usually write the entire query in this syntax so as not to mix both syntaxes.

 var floridaCount = source.Count(s => s.State == "FL"); var items = source .Where(s => s > 5) .Skip(5) .Take(3) .ToList(); 

On the other hand, when a query becomes larger and more complex, the syntax for understanding the query may be clearer, especially after you begin to complicate a few let , group , join , etc.

In the end, I usually use what works best for each particular request.




Update: you fixed your title, so ignore the rest ...

Now about your title: regarding LINQ, IEnumerable and IQueryable are very similar. Both of them have basically the same extension methods (Select, Where, Count, etc.), with the main difference (only?) Is that IEnumerable accepts Func<TIn,TOut> as parameters, and IQueryable accepts Expression<Func<TIn,TOut>> as parameters. You express the same thing (usually lamba expressions), but internally they are completely different.

IEnumerable is the door to LINQ to Objects. LINQ to Objects extension methods can be called in any IEnumerable (arrays, lists, anything you can repeat with foreach ), and Func<TIn,TOut> converted to IL at compile time and works like regular method code at runtime. Note that some other LINQ providers use IEnumerable and therefore actually use LINQ for objects behind the scenes (LINQ to XML, LINQ to DataSet).

IQueryable is used by LINQ to SQL, LINQ to Entities, and other LINQ providers who should check your query and translate it instead of directly executing the code. IQueryable queries and their Expression<Func<TIn,TOut>> do not compile to IL at compile time. Instead, an expression tree is created and can be checked at runtime. This allows you to convert statements to other query languages ​​(for example, T-SQL). The expression tree can be compiled into Func <TIn, TOut> at run time and executed if desired.

An example illustrating the difference can be found in this question , where the OP wants to execute part of a LINQ to SQL query in SQL Server, cast objects to and execute the rest of the query in LINQ to Objects. To do this, all he needs to do is enable IQueryable in IEnumerable, where he wants the switch to happen.

+19
Apr 28 '09 at 5:40
source share

LINQ is the sound word for technology.

IQueryable is the .NET interface that LINQ uses.

Apart from the style, there is no difference between them. Use the style you prefer.

I prefer the first style for a long statement (as shown here), and the second for very short statements.

+3
Apr 28 '09 at 4:41
source share

The where clause in the first example is actually just syntactic sugar for the Where clause in the second method. In fact, you can write your own class that has nothing to do with Linq or IQueryable, and only with the Where method can you use this syntactic sugar. For example:

  public class MyClass { public MyClass Where<T>(Func<MyClass, T> predicate) { return new MyClass { StringProp = "Hello World" }; } public MyClass Select<T>(Func<MyClass, T> predicate) { return new MyClass (); } public string StringProp { get; set; } } 

This is obviously a stupid example, but note that there is a Where method that simply returns a new MyClass with stringprop set to Hello World. To demonstrate:

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

This will spell Hello World. Again, this example is clearly pointless, but it proves that the where syntax is simply looking for the Where method in your code that accepts Func.

+2
Apr 28 '09 at 4:50
source share

Query expressions and extension methods are two ways to do the same. Query expressions are converted to extension methods at compilation - it's just syntactic sugar for people who are more comfortable working with SQL.

When you write this:

 var surveyNames = from s in db.Surveys select s.Name; 

The compiler will convert this to:

 IQueryable<string> surveryNames = db.Surveys.Select(s => s.Name); 

Indeed, I think that query expressions were created only for marketing reasons - an SQL-like language construct that could be used as a catcher when creating LINQ, and not that it offers a lot of actual use. I believe that most people simply use extension methods directly, since they lead to a more unified coding style, rather than a combination of C # and SQL.

+2
Apr 28 '09 at 5:31
source share

1./ The title of the question does not match what you asked.
2./ The title of the question does not make sense. Linq stands for Language Integrated Query and is an umbrella term for many technologies and practices; IQueryable is the interface commonly used to facilitate Linq. you compare Apples and Oranges 3./About your actual question, the main difference is the style, for complex queries like this, my personal preference is the second version, since it clearly shows the progression of the result sets.

+1
Apr 28 '09 at 4:48
source share

Your Sample1 is a top-level Linq view, it is more readable, and when compiled, it is converted to an expression tree, and your Sample2 .

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

you can try under the code to get an expression for a written request

 var exp=x.Expression; 

Expressions are used when the request is less complex.

+1
Apr 28 '09 at 6:22
source share

I think your question is better worded like this: "What is the difference between IEnumerable <T> and IQueryable <T> relative to LINQ"

LINQ queries return an IQueryable <T> by default. IQueryable <T> allows you to add other filters or "suggestions" to your query before executing them.

Your LINQ query (first example) and your LINQ, using a chain of methods (second example), give the same result with different syntax.

You can write a LINQ query as a chain of LINQ methods and vice versa. It depends on your preference.

@Lucas: another IEnumerable <T> value executes a query in memory and IQueryable <T> makes from memory. Meaning, when you are in the foreach iterator, you use IEnumerable, and when you build your query using either extension methods or using LINQ from o in object synatax, you create an IQueryable <T>. IQueryable <T> is executed as soon as you touch Enumerator.

0
Apr 28 '09 at 4:43
source share

Another point worth mentioning is that the Linq extension methods adhere to the C # language, while the material for query analysis is pre-processed as built-in to the compiler. you can go on to define .Select (x => whereas you cannot use from ... where ... select

0
Jun 23 '15 at 6:07
source share



All Articles