如何使用LINQ to Entities初始化匿名类型?

run*_*ack 2 c# linq entity-framework

LINQ to实体支持匿名类型作为返回类型,例如:

var query = from a in b.C select new { Value = a.Value };
Run Code Online (Sandbox Code Playgroud)

和编译器生成的代码将是这样的:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我使用生成的匿名类型实例:

var query = from a in b.C select new f__AnonymousType0<string>(a.Value);
Run Code Online (Sandbox Code Playgroud)

错误:

System.NotSupportedException: Only parameterless constructors and initializers are supported in LINQ to Entities.
Run Code Online (Sandbox Code Playgroud)

将被抛出.

那么匿名类型如何在这里工作?

Jon*_*eet 5

如果编译器必须执行匿名类型初始化程序,那么它最终会调用构造函数.但是在LINQ to Entities - 或任何其他IQueryable基于LINQ的提供程序中 - 代码实际上并未执行...它只是转换为表达式树.

所以在这里你的样本:

var query = from a in b.C select new { Value = a.Value };
Run Code Online (Sandbox Code Playgroud)

...将转换为Expression.New有效代表匿名类型初始值设定项的调用.最重要的是(我相信),它创建了一个NewExpressionMembers属性集,以表明Value属性是从第一个参数的构造函数初始化.

我希望LINQ to Entities能够分析NewExpression出原始代码的含义,并推断出将其转化为SQL需要做些什么.只有构造函数调用它才能做到这一点.