Extension Methods Syntax VS Query Syntax

Extension methods syntax vs query syntax

Honestly, sometimes it can be situational once you start using Funcs and Actions. Say you are using these three funcs:

  Func<DataClasses.User, String> userName = user => user.UserName;
Func<DataClasses.User, Boolean> userIDOverTen = user => user.UserID < 10;
Func<DataClasses.User, Boolean> userIDUnderTen = user => user.UserID > 10;

As you can see the first one replaces the lamdba expression to get the user name, the second replaces a lamdba expression used to check if the ID is lower than 10, and let's face it, the third should be pretty easy to understand now.

NOTE: This is a silly example but it works.

  var userList = 
from user in userList
where userIDOverTen(user)
select userName;

Versus

  var otherList =
userList
.Where(IDIsBelowNumber)
.Select(userName)

In this example, the second is a little less verbose since the extension method can make full use of the Func, but he Linq expression can't since it is look just for a Boolean rather than a Func that returns boolean. However, this is where it might be better to use the expression language. Say you already had a method that takes in more than just a user:

  private Boolean IDIsBelowNumber(DataClasses.User user, 
Int32 someNumber, Boolean doSomething)
{
return user.UserID < someNumber;
}

Note: doSomething is just there because of the where extension method being ok with a method that takes in a user and integer and returns boolean. Kind of annoying for this example.

Now if you look at the Linq query:

  var completeList =
from user in userList
where IDIsBelowNumber(user, 10, true)
select userName;

You're good for it. Now the Extension Method:

  var otherList =
userList
.Where(IDIsBelowNumber????)
.Select(userName)

Without a lambda expression, I really can't call that method. So now what I have to do is create a method that creates a Func based off the original method call.

   private Func<DataClasses.User, Boolean> IDIsBelowNumberFunc(Int32 number)
{
return user => IDIsBelowNumber(user, number, true);
}

And then plug it in:

  var otherList =
userList
.Where(IDIsBelowNumberFunc(10))
.Select(userName)

So you can see, sometimes it may just be easier to use the query approach at times.

Linq query syntax and extension methods

There's nothing you can do in query expressions which can't be done without query expressions - query expressions are just translated into non-query-expression code anyway. There are plenty of queries that can't be written in query expressions though... for example, anything using the Select overload which provides the index as well:

var foo = bar.Select((value, index) => new { value, index });

... and of course, all the many operators which aren't supported by query expressions at all (First etc).

The "minimum" query would use SelectMany for the second from clause, Select for the let clause (introducing a new transparent identifier), Where for the where clause, and Select for the select clause.

LINQ - Query syntax vs method chains & lambda

To answer your question about translation, the query expression will always be translated based on the rules on 7.16 of the C# 4 spec (or the equivalent in the C# 3 spec). In the example where you're asking the question about the Name property, that's not a matter of the query expression translation - it's what the Select and Where methods do with the delegates or expression trees they take as parameters. Sometimes it makes sense to do a projection before filtering, sometimes not.

As for little rules, I only have one: use whichever way is most readable for the query in question. So if the query changes and "which form is more readable" changes at the same time, change the syntax used.

If you're going to use LINQ you should be happy with either syntax, at the very least to read.

I tend to find that queries with multiple range variable (e.g. via SelectMany or Join, or a let clause) end up being more readable using query expressions - but that's far from a hard and fast rule.

What is the difference between LINQ query expressions and extension methods

Update: You have fixed your title, so ignore the rant.

The title 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 incorrect. In your samples, if db.Surveys is an IQueryable, then both your samples are using IQueryable. I will try to answer both questions.

Your two code samples are just different ways of writing the same LINQ queries (assuming they are well-written). The code in sample 1 is just shorthand for the code in sample 2. The compiler treats the code in both samples the same way. Think of the way the C# compiler will treat int? the same as Nullable<System.Int32>. Both the C# and VB.Net languages provide this shorthand query syntax. Other languages might not have this syntax and you would have to use the sample 2 syntax. In fact, other languages might not even support extension methods or lambda expressions, and you would have to use an uglier syntax yet.


Update:

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

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

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

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

But actually extension methods and lambda expressions are shorthand themselves. The compilers emits something like this (not exactly, 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 just a static method in the Queryable class. If your .NET language did not support query syntax, lambdas, or extension methods, that is kinda how you would have to write the code yourself.


What are the benefits of using one style over the other?

For small queries, extension methods can be more compact:

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

Also, the extension method syntax can be more flexible, such as conditional where clauses:

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 only available through extension method syntax (Count(), Aggregate(), Take(), Skip(), ToList(), ToArray(), etc), so if I'll use one of these, I'll usually write the whole query in this syntax to avoid mixing 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 gets bigger and more complex, query comprehension syntax can be clearer, especially once you start complicating with a few let, group, join, etc.

In the end I will usually use whichever works better for each specific query.


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

Now, about your title: With respect to LINQ, IEnumerable and IQueryable are very similar. They both have pretty much the same extension methods (Select, Where, Count, etc), with the main (only?) difference being that IEnumerable takes Func<TIn,TOut> as paremeters and IQueryable takes Expression<Func<TIn,TOut>> as parameters. You express both the same way (usually lamba expressions), but internally they are completely different.

IEnumerable is the doorway to LINQ to Objects. The LINQ to Objects extension methods can be called on any IEnumerable (arrays, lists, anything you can iterate with foreach) and the Func<TIn,TOut> is converted to IL at compile time and runs like a normal method code at run time. Note that some other LINQ providers use IEnumerable and so are actually using LINQ to Objects behind the scenes (LINQ to XML, LINQ to DataSet).

IQueryable is used by LINQ to SQL, LINQ to Entities, and other LINQ providers which need to examine your query and translate it instead of executing your code directly. IQueryable queries and their Expression<Func<TIn,TOut>>s are not compiled into IL at compile time. Instead an expression tree is created and can be examined at run time. This allows the statements to be translated into other query languages (for example T-SQL). An expression tree can be compiled into a Func<TIn,TOut> at run time and executed if desired.

An example that illustrates the difference can be found in this question where the OP wants to do part of a LINQ to SQL query in SQL Server, bring the objects into managed code, and do the rest of the query in LINQ to Objects. To achieve this all he has to do is cast the IQueryable into an IEnumerable where he wants the switch to happen.

Linq mix extension and query syntax

Is it dangerous (for readability, maintainability, or any other reason) to mix query and extension syntax?

The biggest danger I'd see is the potential addition of "surprise" in your code, especially when viewed by other developers.

From a compilation standpoint, the query syntax is translated directly into the extension method calls, so there isn't necessarily a technical problem here. However, this is potentially going to be adding extra method calls that wouldn't, at a first glance, be expected by many developers. This could lead to a potential maintainability problem.

That being said, if done sparingly and with good reason, I don't feel that there is a real problem with mixing the syntax. This is actually quite common - for example, if you want to write in query syntax, but need to fully evaluate, it's often wrapped in parenthesis with .ToList() added - or if you want to use PLINQ with query syntax, it's often from x in collection.AsParallel(), which is technically mixing syntax as well...

Translate Query Syntax to Extension Methods Syntax

Below I'll answer your question exactly. However, I don't really see why you would want to have your query translated to extension methods, so I think this answer is not the answer you're looking for. If so, could you dive into the terminology and rephrase the question?


First: LINQ query syntax is just nice syntactic sugar for extension methods. Your code:

return (from person in this.context.Persons
from email in this.context.EmailAddresses
where email.EmailAddress == emailAddress
select person).FirstOrDefault();

Below is the LINQ query syntax translated to extension methods. The two are equivalent, they do exactly the same and give the same result:

return this.context.Persons
.SelectMany(p => this.context.EmailAddresses,
(p, e) => new { Person = p, Email = e})
.Where(pe => pe.Email == pe.Person)
.Select(pe => pe.Person)
.FirstOrDefault();

It is just not as nice to read, and it is harder to understand.

Linq Query syntax vs. Method Chain: return type

from device in dataSet.devices
where !device.paramValues[i].Equals(double.NaN)
select device.paramValues[i]

is transformed into methods as follows:

dataSet.devices
.Where(device => !device.paramValues[i].Equals(double.NaN))
.Select(device => device.paramValues[i]);

Adding your OrderBy call you get

dataSet.devices
.Where(device => !device.paramValues[i].Equals(double.NaN))
.Select(device => device.paramValues[i])
.OrderBy(val => val);

The other query

from device in dataSet.devices
where !device.paramValues[i].Equals(double.NaN)
orderby device.paramValues[i]
select device.paramValues[i];

is transformed to

dataSet.devices
.Where(device => !device.paramValues[i].Equals(double.NaN))
.OrderBy(device => device.paramValues[i])
.Select(device => device.paramValues[i]);

As you can see, it's not exactly the same method chain, and that's because you get different object as a result. Content is the same, but the type returned is not.

LINQ Keywords vs. Methods

The query syntax will be converted into the method syntax by the compiler in a first pass, and then compiled from that method syntax into IL code in a second pass. There is no difference in the resulting compiled code between code written using the query syntax verses code written directly in method syntax. (Although not all of the methods are represented in query syntax, so some queries cannot be written without partial or complete use of method syntax.)

The only difference is the personal preference of the coder; what you find easier to read or write.

From my personal experiences certain types of queries are easier to read and/or write in one syntax over the other, but that's entirely a matter of opinion and does vary between people. Use whichever you're most comfortable with in any given situation.

How to write this code using the Linq Extension Method-Syntax?

If you order does not refer back to a customer, the trick is to first create a dataset which keeps the customers and orders linked together:

customers
.SelectMany(c => c.Orders.Select(o => new {
cust = c,
ord = o
}))

Then on this CustomerOrder (co) you can apply your join:

...
.Join(products,
co => co.ord.ProductID,
prod => prod.ProductID,
(co,prod) => new {
co.cust.Name,
co.ord.ProductID,
OrderAmount = ord.Quantity * prod.Price});

asp.net mvc 4 linq extension method syntax join

You have mixed query and method syntax in a wrong way.

 var model = _db.Seuni
.Join(_db.Keuni,
c => c.klasaid,
o => o.klasaid,
(c, o) => new { o.emriklases, c.emristudent, c.studentid, c.nota })
.OrderByDescending(r => r.nota);

Or with query (method for order) syntax

// query syntax
var model = (from o in _db.Keuni
join c in _db.Seuni on o.klasaid equals c.klasaid
select new { o.emriklases, c.emristudent, c.studentid, c.nota })
.OrderByDescending(r => r.nota);


Related Topics



Leave a reply



Submit