Linq - Query Syntax VS Method Chains & Lambda

.NET LINQ query syntax vs method chain

No, because they are compiled into exactly the same code.

Basically query expressions are "pre-processed" by the compiler into "C# 3 without query expressions" and then the rules of overloading, lambda expression translation etc are applied as normal. It's a really elegant system which means that the rules for query expressions are limited to just one small bit of the spec.

Of course, there are various things you can write in "chained method" syntax which can't be written in query expression syntax, either due to using other overloads or the methods simply not being supported (e.g. Count()) - but unless you're using those, the compiled code will be exactly the same. Pick the most readable alternative for any particular scenario.

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 should you use for joining in LINQ, Query syntax or method syntax?

There is no difference. Your first version (query language) is translated lexically into the second one (method syntax) before "real" compilation. The query language is only syntactic sugar and transformed into method calls. These calls are then compiled (if possible - the translation itself does not care about the correctness of the result, e.g. if People.Join even is valid C# and there is such a Join method in whatever People might be).

There maybe a difference in that this translation uses an explicit Select call instead of the resultSelector parameter of the Join method, but even that does not measurably impact performance.

This article by Jon Skeet helped me understand the transformation from query language to method syntax.


To answer the question "What should you use": this is really up to you. Consider:

  • what is more readable/understandable to you (and your co-workers!)
  • complex queries often are more readable in query syntax, the SQL-like style can be easier to read than a long chain of method calls
  • Note that every query syntax expression can be expressed as method calls, but not all method calls can be expressed in query syntax
  • mixing both syntaxes in a single query is often more confusing than sticking to one of them

LINQ Lambda vs Query Syntax Performance

I have simulated your situation. And yes, there is difference between execution times of these queries. But, the reason of this difference isn't syntax of the query. It doesn't matter if you have used method or query syntax. Both yields the same result because query expres­sions are trans­lated into their lambda expres­sions before they’re com­piled.

But, if you have paid attention the two queries aren't same at all.Your second query will be translated to it's lambda syntax before it's compiled (You can remove ToList() from query, because it is redundant):

pTasks.Where(x => x.StatusID == (int)BusinessRule.TaskStatus.Pending).Count();

And now we have two Linq queries in lambda syntax. The one I have stated above and this:

pTasks.Count(x => x.StatusID == (int)BusinessRule.TaskStatus.Pending);

Now, the question is:

Why there is difference between execution times of these two queries?



Let's find the answer:

We can understand the reason of this difference by reviewing these:

- .Where(this IEnumerable<TSource> source, Func<TSource, bool> predicate).Count(this IEnumerable<TSource> source)

and

- Count(this IEnumerable<TSource> source, Func<TSource, bool> predicate);

Here is the implementation of Count(this IEnumerable<TSource> source, Func<TSource, bool> predicate):

public static int Count<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
if (source == null) throw Error.ArgumentNull("source");
if (predicate == null) throw Error.ArgumentNull("predicate");
int count = 0;
foreach (TSource element in source) {
checked {
if (predicate(element)) count++;
}
}
return count;
}

And here is the Where(this IEnumerable<TSource> source, Func<TSource, bool> predicate):

public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
if (source == null)
throw Error.ArgumentNull("source");
if (predicate == null)
throw Error.ArgumentNull("predicate");
if (source is Iterator<TSource>)
return ((Iterator<TSource>)source).Where(predicate);
if (source is TSource[])
return new WhereArrayIterator<TSource>((TSource[])source, predicate);
if (source is List<TSource>)
return new WhereListIterator<TSource>((List<TSource>)source, predicate);
return new WhereEnumerableIterator<TSource>(source, predicate);
}

Let's pay an attention to Where() implementation. It will return WhereListIterator() if your collection is List, but Count() will just iterate over source.
And in my opinion they have made some speed up in the implementation of WhereListIterator. And after this we are calling Count() method which takes no predicate as input and only will iterate on filtered collection.


And regarding to that speed up in the implementation of WhereListIterator:

I have found this question in SO: LINQ performance Count vs Where and Count. You can read @Matthew Watson answer there. He explains the performance difference between these two queries. And the result is:
The Where iterator avoids indirect virtual table call, but calls iterator methods directly.
As you see in that answer call instruction will be emitted instead of callvirt. And, callvirt is slower than call:

From bookCLR via C#:

When the callvirt IL instruction is used to call a virtual instance
method, the CLR discovers the actual type of the object being used to
make the call and then calls the method polymorphically. In order to
determine the type, the variable being used to make the call must not
be null. In other words, when compiling this call, the JIT compiler
generates code that verifes that the variable’s value is not null. If
it is null, the callvirt instruction causes the CLR to throw a
NullReferenceException. This additional check means that the callvirt
IL instruction executes slightly more slowly than the call
instruction.

Linq query or Lambda expression?

Query Expression compiles into Method Expression (Lambda expression), so there shouldn't be any difference, In your code though you are accessing First and FirstOrDefault which would behave differently.

See: Query Syntax and Method Syntax in LINQ (C#)

and LINQ Query Expressions (C# Programming Guide)

At compile time, query expressions are converted to Standard Query
Operator method calls according to the rules set forth in the C#
specification. Any query that can be expressed by using query syntax
can also be expressed by using method syntax. However, in most cases
query syntax is more readable and concise.

Can a method chain be called LINQ?

LINQ can be written in two different ways.

One is by writing a query using LINQ declarative query syntax:

var query = from x in source
where condition
select x.Property

And the other is by using LINQ's extension methods:

var query = source.Where(condition).Select(x => x.Property);

Both queries are identical and will produce the same result (well, compiler error in this over-simplified example but it's the thought that counts :-))

The c# compiler translates the query into method calls.

This means that everything you write as a query can be also written using method chains. Please note, however, that the opposite is false - Some queries can only be written using Linq's extension methods.

For further reading, here's what Microsoft have to say about it.

Note the second paragraph starts with this:

Query syntax and method syntax are semantically identical, but many people find query syntax simpler and easier to read.

btw, if it was'nt already clear, the reason that System.Linq is mandatory for the method chaining syntax also is because the linq extension methods belongs to this namespace.

When to use lambda expressions instead of a Where clause in LINQ

Take a look at this article: LINQ Query Syntax versus Method Syntax
:

In general, we recommend query syntax
because it is usually simpler and more
readable; however there is no semantic
difference between method syntax and
query syntax. In addition, some
queries, such as those that retrieve
the number of elements that match a
specified condition, or that retrieve
the element that has the maximum value
in a source sequence, can only be
expressed as method calls. The
reference documentation for the
standard query operators in the
System.Linq namespace generally uses
method syntax. Therefore, even when
getting started writing LINQ queries,
it is useful to be familiar with how
to use method syntax in queries and in
query expressions themselves.

And also this question: LINQ: Dot Notation vs Query Expression

Linq Intermediate Object in method chain for Where and Select?

If you use LINQ with query syntax, you have the let keyword that creates a temporary to use later in the query. When the query syntax is translated by the compiler into fluent/lambda syntax, the let is translated into a Select that bundles the temporary values with any values you need to carry into future methods.

You can do the same manually:

var rowData = registersRows
.Select(r => new { RowIndex = r.RowIndex, cells = r.Elements<Cell>().ToList() })
.Select(rc => new { rc.RowIndex, rc.cells, A = GetCellText(rc.cells, "A", rc.RowIndex, sharedStringTableItems) })
.Where(rca => included.Contains(rca.A))
.Select(rca => new RegistersRow {
StoreNumber = rca.A,
ChannelName = GetCellText(rca.cells, "D", rca.RowIndex, sharedStringTableItems),
ChannelDisplayName = GetCellText(rca.cells, "E", rca.RowIndex, sharedStringTableItems),
PhysicalDeviceName = GetCellText(rca.cells, "F", rca.RowIndex, sharedStringTableItems),
FriendlyName = GetCellText(rca.cells, "G", rca.RowIndex, sharedStringTableItems),
DisplayNameInLabel = GetCellText(rca.cells, "H", rca.RowIndex, sharedStringTableItems),
NumberOfRegisters =
int.Parse(GetCellText(rca.cells, "K", rca.RowIndex, sharedStringTableItems))
})
.ToList();

Linq query or Lambda expression?

Query Expression compiles into Method Expression (Lambda expression), so there shouldn't be any difference, In your code though you are accessing First and FirstOrDefault which would behave differently.

See: Query Syntax and Method Syntax in LINQ (C#)

and LINQ Query Expressions (C# Programming Guide)

At compile time, query expressions are converted to Standard Query
Operator method calls according to the rules set forth in the C#
specification. Any query that can be expressed by using query syntax
can also be expressed by using method syntax. However, in most cases
query syntax is more readable and concise.

Difference between lamda where condition and linq where condition?

Please let me know what is correct?

e.gLambda: context.tablename.where(condition);// Should I go with this

LINQ: (from T in tablename where t.(condition));// or this?

Short answer: it doesn't really matter. Since context.tablename ultimately returns an IQueryable<T>, Entityframework will not try to hit the database until you try to iterate the final result from your expression, not to mention, .ToArray() and .ToList() each, does that iteration for you.

Either you used LINQ expression syntax (which gets compiled as LINQ methods) or LINQ methods, when you attempt to begin iterating the results, Entityframework creates an Expression tree for you underneath the hood that consists of your query altogether (including Wheres, Joins, GroupBys, etc). Since the structure of a LINQ might not percisely match the structure of a SQL query (or whatever data-source query), depending on the source (i.e database, e.g SQL Server), Entityframework then attempts to make the best possible optimization to your expression tree so that its structure would match an executable query on the source (e.g SQL Server query). Finally, it translates that expression tree into an actual query and executes it against the data source, and return your data (after doing all the mapping of course).

If you really, and I mean REALLY want to go through the complications of how an IQueryable engine works, I'd suggest taking a walk through Matt Warren's series: 'LINQ: Building an IQueryable provider series'. That's not actually Entityframework but it shares the same concept.



Related Topics



Leave a reply



Submit