在使用EntityFramework时,当我试图编译以下代码时,我得到了错误“带有语句体的lambda表达式不能转换为表达式树”:

Obj[] myArray = objects.Select(o =>
{
    var someLocalVar = o.someVar;

    return new Obj() { 
    Var1 = someLocalVar,
    Var2 = o.var2 };
}).ToArray();

我不知道这个错误意味着什么,最重要的是如何修复它。任何帮助吗?


当前回答

LINQ to SQL返回对象实现了IQueryable接口。因此,对于Select方法谓词参数,您应该只提供单个没有主体的lambda表达式。

这是因为SQL代码的LINQ不是在程序内部执行,而不是像SQL server或其他服务器那样在远程端执行。这种延迟加载执行类型是通过实现IQueryable来实现的,其中它的期望委托被包装在表达式类型类中,如下所示。

Expression<Func<TParam,TResult>>

表达式树不支持带有体的lambda表达式,它只支持单行lambda表达式,如var id = cols。Select(col => col.id);

因此,如果您尝试以下代码将无法工作。

Expression<Func<int,int>> function = x => {
    return x * 2;
}

以下将按预期工作。

Expression<Func<int,int>> function = x => x * 2;

其他回答

你可以在IEnumerable集合的lamba表达式中使用语句体。 试试这个:

Obj[] myArray = objects.AsEnumerable().Select(o =>
{
    var someLocalVar = o.someVar;

    return new Obj() 
    { 
        Var1 = someLocalVar,
        Var2 = o.var2 
    };
}).ToArray();

注意: 在使用此方法时要仔细考虑,因为这样,所有查询结果都将保存在应用程序的内存中,这可能会对其余代码产生不必要的副作用。

对于您的具体情况,body是用于创建变量,切换到IEnumerable将强制所有操作在客户端处理,我提出以下解决方案。

Obj[] myArray = objects
.Select(o => new
{
    SomeLocalVar = o.someVar, // You can even use any LINQ statement here
    Info = o,
}).Select(o => new Obj()
{
    Var1 = o.SomeLocalVar,
    Var2 = o.Info.var2,
    Var3 = o.SomeLocalVar.SubValue1,
    Var4 = o.SomeLocalVar.SubValue2,
}).ToArray();

编辑:重命名为c#编码惯例

Arr是Obj的基础类型吗?Obj类存在吗?你的代码只有在Arr是Obj的基类型时才能工作。你可以试试这个:

Obj[] myArray = objects.Select(o =>
{
    var someLocalVar = o.someVar;

    return new Obj() 
    { 
       Var1 = someLocalVar,
       Var2 = o.var2 
    };
}).ToArray();

LINQ to SQL返回对象实现了IQueryable接口。因此,对于Select方法谓词参数,您应该只提供单个没有主体的lambda表达式。

这是因为SQL代码的LINQ不是在程序内部执行,而不是像SQL server或其他服务器那样在远程端执行。这种延迟加载执行类型是通过实现IQueryable来实现的,其中它的期望委托被包装在表达式类型类中,如下所示。

Expression<Func<TParam,TResult>>

表达式树不支持带有体的lambda表达式,它只支持单行lambda表达式,如var id = cols。Select(col => col.id);

因此,如果您尝试以下代码将无法工作。

Expression<Func<int,int>> function = x => {
    return x * 2;
}

以下将按预期工作。

Expression<Func<int,int>> function = x => x * 2;

对象是Linq-To-SQL数据库上下文吗?在这种情况下,只能使用=>运算符右侧的简单表达式。原因是,这些表达式不会被执行,而是被转换为SQL,然后对数据库执行。 试试这个

Arr[] myArray = objects.Select(o => new Obj() { 
    Var1 = o.someVar,
    Var2 = o.var2 
}).ToArray();