How are anonymous types initialized with LINQ to Entities?

LINQ to entities support anonymous type as return type, such as:

var query = from a in b.C select new { Value = a.Value };

and code generated by the compiler will be something like:

private class f__AnonymousType0<j__TPar>
{
    private readonly j__TPar i__Field;
    public j__TPar Value
    {
        get { return i__Field; }
    }

    public f__AnonymousType0(j__TPar Value)
    {
        i__Field = Value;
    }
}

But if I use the generated anonymous type instance:

var query = from a in b.C select new f__AnonymousType0<string>(a.Value);

error:

System.NotSupportedException: Only parameterless constructors and initializers are supported in LINQ to Entities.

will be thrown.

So how did anonymous type work here?

Jon Skeet
people
quotationmark

If the compiler has to execute an anonymous type initializer, then it ends up calling the constructor. But in LINQ to Entities - or any other IQueryable-based LINQ provider - the code isn't actually executed... it's just converted into an expression tree.

So in your sample here:

var query = from a in b.C select new { Value = a.Value };

... that will be converted into a call to Expression.New which effectively represents the anonymous type initializer. Crucially (I believe), it creates a NewExpression with the Members property set to indicate that the Value property was initialized from the first argument to the constructor.

I expect that LINQ to Entities analyzes that NewExpression to work out what your original code meant, and infer what it needs to do to turn it into SQL. It can't do that with just a constructor call.

people

See more on this question at Stackoverflow