I love these discussions, simply because in most cases, in my opinion, it boils down to personal style. Recently I was discussing with a colleague the different ways a LINQ query could be written for the same result (the discussion was based on code for Entity Framework for .NET 3.5).
Consider the following code snippets; the first uses what has been coined as “Query Comprehension Syntax” and the second is based on Method Chains (also seen referred to as “Extension Methods”):
Query Copmrehension Syntax
var query = (from e in EmployeeSet
from o in OrderSet
from c in CustomerSet
where e.EmployeeID == o.Employees.EmployeeID &&
o.Customers.CustomerID == c.CustomerID
group e by new { EmployeeInstance = e, CustomerInstance = c } into result
orderby result.Key.EmployeeInstance.LastName
select result);
Method Chain (Extension Method) Syntax
var query = (EmployeeSet
.SelectMany(e => OrderSet, (e, o) => new {e, o})
.SelectMany(@t => CustomerSet,(@t, c) => new {@t, c})
.Where(@t => @t.@t.e.EmployeeID == @t.@t.o.Employees.EmployeeID &&
@t.@t.o.Customers.CustomerID == @t.c.CustomerID)
.GroupBy(@t => new {EmployeeInstance = @t.@t.e, CustomerInstance = @t.c}, @t => @t.@t.e)
.OrderBy(result => result.Key.EmployeeInstance.LastName));
Well? What is the difference?
In both cases they are trying to emulate the following SQL (albeit with a bit more beef – i.e. returning the complete entities – not just the strings):
[code lang="sql"]
select e.FirstName, e.LastName, c.ContactName
from Customers c, Employees e, Orders o
where e.EmployeeID = o.EmployeeID
and o.CustomerID = c.CustomerID
group by e.FirstName, e.LastName, c.ContactName
order by e.LastName
Ok. What is the difference?
Looking at the output we get the exact same result in both cases (when put through the following algorithm):
Dictionary<BaseEmployee, List<BaseCustomer>> retVal = new Dictionary<BaseEmployee, List<BaseCustomer>>();
string previousEmployeeName = string.Empty;
BaseEmployee previousEmployeeInstance = null;
foreach (var queryItem in query)
{
BaseEmployee employee = ConvertToBase(queryItem.Key.EmployeeInstance);
string currentEmployeeName = string.Format("{0}-{1}", employee.FirstName, employee.LastName);
BaseCustomer customer = ConvertToBase(queryItem.Key.CustomerInstance);
if (currentEmployeeName != previousEmployeeName)
{
previousEmployeeName = currentEmployeeName;
retVal.Add(employee, new List<BaseCustomer>());
previousEmployeeInstance = employee;
}
retVal[previousEmployeeInstance].Add(customer);
}
So? What is the difference?
And looking at it through SQL Profiler, guess what? That's right! We get exactly the same result - SQL is exactly the same!
Alright already! WHAT IS THE DIFFERENCE?
Really? It would appear to be - readability... In cases where the query is long and drawn out, most of us would be quite comfortable with the QCS format as it is closer to what we are accustomed to seeing in T-SQL; however the Method Chain (Extension Methods) format is much more compact for smaller queries - much neater in my mind.
The whole discussion came about because of the functionality of ReSharper to build the Method Chain. If you hover over a QCS LINQ query, the ReSharper "lightbulb" will appear to give you the following option:

And VOILA! You have now converted it to a Method Chain... the only gotcha is that you can't change it back (forgetting the use of CTRL + Z).
Similar discussions have appeared here and here on Stack Overflow.
<Update June 10, 2009>:I wrapped some timing around both syntaxes and this was the result:
First time run:
ExtensionMethod syntax: 00:00:01.0271109
QueryComprehensionSyntax syntax: 00:00:01.0216957
Subsequent runs
ExtensionMethod syntax: 00:00:00.0976207
QueryComprehensionSyntax syntax: 00:00:00.0917982
ExtensionMethod syntax: 00:00:00.0955029
QueryComprehensionSyntax syntax: 00:00:00.0908081
ExtensionMethod syntax: 00:00:00.0974213
QueryComprehensionSyntax syntax: 00:00:00.0970167
ExtensionMethod syntax: 00:00:00.0905830
QueryComprehensionSyntax syntax: 00:00:00.1007809
ExtensionMethod syntax: 00:00:00.0895348
QueryComprehensionSyntax syntax: 00:00:00.0965262
ExtensionMethod syntax: 00:00:00.0972316
QueryComprehensionSyntax syntax: 00:00:00.0886347
ExtensionMethod syntax: 00:00:00.1030211
QueryComprehensionSyntax syntax: 00:00:00.0927539
ExtensionMethod syntax: 00:00:00.0943354
QueryComprehensionSyntax syntax: 00:00:00.0919315
ExtensionMethod syntax: 00:00:00.0938015
QueryComprehensionSyntax syntax: 00:00:00.0908355
ExtensionMethod syntax: 00:00:00.0921636
QueryComprehensionSyntax syntax: 00:00:00.0972665
