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

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

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

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


当前回答

正如在其他回复中所述,您只能使用=>操作符右侧的简单表达式。我建议这个解决方案,它只包括创建一个方法,做你想要在lambda中有的事情:

public void SomeConfiguration() {
    // ...
    Obj[] myArray = objects.Select(o => Method()).ToArray();
    // ..
}

public Obj Method() {
    var someLocalVar = o.someVar;

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

其他回答

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;

不知道更多关于你在做什么(Linq2Objects, Linq2Entities, Linq2Sql?),这应该使它工作:

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

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

9年的时间太晚了,但是用不同的方法来解决你的问题(没有人提到过吗?)

语句体在Func<>时工作得很好,但在Expression<Func<>>时就不行了。这个IQueryable。Select需要表达式<>,因为它们可以转换为实体框架- Func<>不能。

所以你要么使用AsEnumerable并开始处理内存中的数据(不推荐,如果不是真的必要的话),要么继续使用IQueryable<>,这是推荐的。 有一个叫linq查询的东西可以让一些事情变得更简单:

IQueryable<Obj> result = from o in objects
                         let someLocalVar = o.someVar
                         select new Obj
                         {
                           Var1 = someLocalVar,
                           Var2 = o.var2
                         };

通过让你可以定义一个变量并在select(或where,…)中使用它-你可以继续使用IQueryable,直到你真正需要执行和获取对象。

然后你可以Obj[] myArray = result.ToArray()

这意味着你不能在lambda表达式需要转换为表达式树的地方使用带有“语句体”的lambda表达式(即使用花括号的lambda表达式)(例如使用linq2sql时的情况)。