LINQ query syntax vs method syntax

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

No comments:

HOWTO: Repair Logitech M325 Mouse

FixIt says that you will find single screw under CE label. It isn't always true.