IT story

"명령문 본문이있는 람다 식은 식 트리로 변환 할 수 없습니다"

hot-time 2020. 6. 6. 08:11
반응형

"명령문 본문이있는 람다 식은 식 트리로 변환 할 수 없습니다"


EntityFramework 사용시 A lambda expression with a statement body cannot be converted to an expression tree다음 코드를 컴파일하려고 할 때 " " 오류가 발생 합니다.

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

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

오류가 무엇을 의미하는지, 무엇보다도 오류를 해결하는 방법을 모르겠습니다. 어떤 도움?


objectsLinq에 - 투 - SQL 데이터베이스 컨텍스트는? 이 경우 => 연산자 오른쪽에 간단한 표현식 만 사용할 수 있습니다. 그 이유는 이러한 표현식이 실행되지 않지만 데이터베이스에 대해 실행되도록 SQL로 변환되기 때문입니다. 이 시도

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

IEnumerable 콜렉션에 대해 람바 표현식에서 명령문 본문을 사용할 수 있습니다 . 이거 한번 해봐:

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

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


주의 사항 : 이 방법을 사용할 때 신중하게 생각하십시오 . 이렇게하면 모든 쿼리 결과가 메모리에 저장되어 나머지 코드에 원하지 않는 부작용이 발생할 수 있습니다.


즉, 람다 식을 표현식 트리로 변환해야하는 위치 (예 : linq2sql을 사용하는 경우)에서 "statement body"(예 : 중괄호를 사용하는 람다 식)와 함께 람다 식을 사용할 수 없습니다. .


수행중인 작업 (Linq2Objects, Linq2Entities, Linq2Sql?)에 대해 더 많이 알지 못하면 작동해야합니다.

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

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

이 선택 과부하를 사용하십시오.

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

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

LINQ to SQL 리턴 오브젝트가 IQueryable인터페이스 를 구현하고있었습니다 . 따라서 Select메소드 술어 매개 변수의 경우 본문없이 단일 람다 표현식 만 제공해야합니다.

This is because LINQ for SQL code is not execute inside program rather than on remote side like SQL server or others. This lazy loading execution type were achieve by implementing IQueryable where its expect delegate is being wrapped in Expression type class like below.

Expression<Func<TParam,TResult>>

Expression tree do not support lambda expression with body and its only support single line lambda expression like var id = cols.Select( col => col.id );

So if you try the following code won't works.

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

The following will works as per expected.

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

It means that a Lambda expression of type TDelegate which contains a ([parameters]) => { some code }; cannot be converted to an Expression<TDelegate>. It's the rule.

Simplify your query. The one you provided can be rewritten as the following and will compile:

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

Is Arr a base type of Obj? Does the Obj class exist? Your code would work only if Arr is a base type of Obj. You can try this instead:

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

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

For your specific case, the body is for creating a variable, and switching to IEnumerable will force all the operations to be processed on client-side, I propose the following solution.

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

Edit: Rename for C# Coding Convention

참고URL : https://stackoverflow.com/questions/5179341/a-lambda-expression-with-a-statement-body-cannot-be-converted-to-an-expression

반응형