LINQ query syntax is close to native language and it's simple and easy to read.
The method syntax is powerfull but definitively more complicated tool.
For example take one previous listing
MySqlConnection conn = new MySqlConnection("SERVER=localhost; DATABASE=employees;UID=root;PASSWORD=");
var emp = new EmployeeDataContext(conn);
var lastSalaries = (from s in emp.Salaries
orderby s.EmpNo ascending, s.ToDate descending
group s by s.EmpNo into grp
let o = grp.First()
let averageSalary = (from s in emp.Salaries select s.Salary1).Average()
select new { o.EmpNo, o.Salary1, MoreOrLess = (averageSalary > o.Salary1) }).Take(10);
foreach (object b in lastSalaries)
Console.WriteLine(b);
Listing 12.1
and convert it into new code using corresponding method syntax
MySqlConnection conn = new MySqlConnection("SERVER=localhost; DATABASE=employees;UID=root;PASSWORD=");
var emp = new EmployeeDataContext(conn);
var lastSalaries = emp.Salaries.OrderBy(s => s.EmpNo)
.ThenByDescending(s => s.ToDate)
.GroupBy(s => s.EmpNo)
.Select(grp => new { o = grp.First(), averageSalary = emp.Salaries.Average(s => s.Salary1) })
.Select(e => new { e.o.EmpNo, e.o.Salary1, MoreOrLess = (e.averageSalary > e.o.Salary1) })
.Take(10);
foreach (object b in lastSalaries)
Console.WriteLine(b);
Listing 12.2
now let's open executable file with Reflector and have look at it. Can you imagine what kind of code was generated?!
MySqlConnection connection = new MySqlConnection("SERVER=localhost; DATABASE=employees;UID=root;PASSWORD=");
EmployeeDataContext emp = new EmployeeDataContext(connection);
var lastSalaries = emp.Salaries.OrderBy(
Expression.Lambda>(Expression.Property(expression = Expression.Parameter(typeof(Salary), "s"),
(MethodInfo) methodof(Salary.get_EmpNo)), new ParameterExpression[] { expression }))
.ThenByDescending(Expression.Lambda>(Expression.Property(expression2 = Expression.Parameter(typeof(Salary), "s"),
(MethodInfo) methodof(Salary.get_ToDate)), new ParameterExpression[] { expression2 }))
.GroupBy(Expression.Lambda>(Expression.Property(expression3 = Expression.Parameter(typeof(Salary), "s"),
(MethodInfo) methodof(Salary.get_EmpNo)), new ParameterExpression[] { expression3 }))
.Select(Expression.Lambda(Expression.New((ConstructorInfo) methodof(<>f__AnonymousType0, Salary>..ctor,
<>f__AnonymousType0, Salary>), new Expression[] {
expression4 = Expression.Parameter(typeof(IGrouping), "grp"),
Expression.Call(null, (MethodInfo) methodof(Enumerable.First), new Expression[] { expression4 }) },
new MethodInfo[] { (MethodInfo) methodof(<>f__AnonymousType0, Salary>.get_grp,
<>f__AnonymousType0, Salary>),
(MethodInfo) methodof(<>f__AnonymousType0, Salary>.get_o,
<>f__AnonymousType0, Salary>) }), new ParameterExpression[] { expression4 }))
.Select(Expression.Lambda(Expression.New((ConstructorInfo) methodof(<>f__AnonymousType1<<>f__AnonymousType0,
Salary>, double>..ctor, <>f__AnonymousType1<<>f__AnonymousType0, Salary>, double>),
new Expression[] { expression5 = Expression.Parameter(typeof(<>f__AnonymousType0, Salary>), "<>h__TransparentIdentifier0"),
Expression.Call(null, (MethodInfo) methodof(Queryable.Average),
new Expression[] { Expression.Call(null, (MethodInfo) methodof(Queryable.Select),
new Expression[] { Expression.Property(Expression.Constant(emp), (MethodInfo) methodof(EmployeeDataContext.get_Salaries)),
Expression.Quote(Expression.Lambda>(Expression.Property(expression6 = Expression.Parameter(typeof(Salary), "s"),
(MethodInfo) methodof(Salary.get_Salary1)), new ParameterExpression[] { expression6 })) }) }) },
new MethodInfo[] { (MethodInfo) methodof(<>f__AnonymousType1<<>f__AnonymousType0, Salary>, double>.get_<>h__TransparentIdentifier0, <>f__AnonymousType1<<>f__AnonymousType0, Salary>, double>),
(MethodInfo) methodof(<>f__AnonymousType1<<>f__AnonymousType0, Salary>, double>.get_averageSalary, <>f__AnonymousType1<<>f__AnonymousType0, Salary>, double>) }),
new ParameterExpression[] { expression5 })).Select(Expression.Lambda(Expression.New((ConstructorInfo) methodof(<>f__AnonymousType2..ctor, <>f__AnonymousType2),
new Expression[] { Expression.Property(Expression.Property(Expression.Property(expression7 = Expression.Parameter(typeof(<>f__AnonymousType1<<>f__AnonymousType0, Salary>, double>),
"<>h__TransparentIdentifier1"), (MethodInfo) methodof(<>f__AnonymousType1<<>f__AnonymousType0, Salary>, double>.get_<>h__TransparentIdentifier0, <>f__AnonymousType1<<>f__AnonymousType0, Salary>, double>)),
(MethodInfo) methodof(<>f__AnonymousType0, Salary>.get_o, <>f__AnonymousType0, Salary>)), (MethodInfo) methodof(Salary.get_EmpNo)),
Expression.Property(Expression.Property(Expression.Property(expression7, (MethodInfo) methodof(<>f__AnonymousType1<<>f__AnonymousType0, Salary>, double>.get_<>h__TransparentIdentifier0, <>f__AnonymousType1<<>f__AnonymousType0, Salary>, double>)),
(MethodInfo) methodof(<>f__AnonymousType0, Salary>.get_o, <>f__AnonymousType0, Salary>)), (MethodInfo) methodof(Salary.get_Salary1)), Expression.GreaterThan(Expression.Property(expression7,
(MethodInfo) methodof(<>f__AnonymousType1<<>f__AnonymousType0, Salary>, double>.get_averageSalary, <>f__AnonymousType1<<>f__AnonymousType0, Salary>, double>)),
Expression.Convert(Expression.Property(Expression.Property(Expression.Property(expression7, (MethodInfo) methodof(<>f__AnonymousType1<<>f__AnonymousType0, Salary>, double>.get_<>h__TransparentIdentifier0, <>f__AnonymousType1<<>f__AnonymousType0, Salary>, double>)),
(MethodInfo) methodof(<>f__AnonymousType0, Salary>.get_o, <>f__AnonymousType0, Salary>)),
(MethodInfo) methodof(Salary.get_Salary1)), typeof(double))) }, new MethodInfo[] { (MethodInfo) methodof(<>f__AnonymousType2.get_EmpNo, <>f__AnonymousType2),
(MethodInfo) methodof(<>f__AnonymousType2.get_Salary1, <>f__AnonymousType2),
(MethodInfo) methodof(<>f__AnonymousType2.get_MoreOrLess, <>f__AnonymousType2) }),
new ParameterExpression[] { expression7 })).Take(10);
foreach (object obj2 in lastSalaries)
{
Console.WriteLine(obj2);
}
Listing 12.3
I like it ;)