문제

정적 기능을 두 가지 표현식에 쓰려고하지만 다음 오류를받습니다.

매개 변수 '항목'은 범위가 아닙니다.

설명 : 현재 웹 요청을 실행하는 동안 처리되지 않은 예외가 발생했습니다. 오류 및 코드에서 시작된 위치에 대한 자세한 내용은 스택 추적을 검토하십시오.

예외 세부 사항 : System.InvalidOperationException : 매개 변수 '항목'은 범위가 아닙니다.

방법:

public static Expression<Func<T, bool>> OrExpressions(Expression<Func<T, bool>> left, Expression<Func<T, bool>> right)
{
    // Define the parameter to use
    var param = Expression.Parameter(typeof(T), "item");

    var filterExpression = Expression.Lambda<Func<T, bool>>
         (Expression.Or(
             left.Body,
             right.Body
          ), param);
    // Build the expression and return it
    return (filterExpression);
}

편집하다: 더 많은 정보 추가

표현이 아래의 방법에서 나오는 표현은 잘 실행됩니다. 더 나은 방법이 있거나 결과가 있다면 나는 모두 귀입니다. 또한, 나는 얼마나 많은 사람들이 미리 존재하는지 모른다.

public static Expression<Func<T, bool>> FilterExpression(string filterBy, object Value, FilterBinaryExpression binaryExpression)
{
    // Define the parameter to use
    var param = Expression.Parameter(typeof(T), "item");

    // Filter expression on the value
    switch (binaryExpression)
    {
        case FilterBinaryExpression.Equal:
            {
                // Build an expression for "Is the parameter equal to the value" by employing reflection
                var filterExpression = Expression.Lambda<Func<T, bool>>
                    (Expression.Equal(
                        Expression.Convert(Expression.Property(param, filterBy), typeof(TVal)),
                        Expression.Constant(Value)
                     ),
                    param);
                // Build the expression and return it
                return (filterExpression);
            }

편집하다: 더 많은 정보 추가

또는 또는 더 좋은 방법이 있습니까? 현재 .where (제약)는 제약 조건이 유형 표현식의 경우에도 잘 작동합니다. 어디에서 (제약 1 또는 제약 조건 2) (제약 조건에 적합)를 어떻게 할 수 있습니까?

미리 감사드립니다!

도움이 되었습니까?

해결책

문제는 방법에서 당신이 만들어 낸 표현이 두 표현의 본문을 재사용한다는 것입니다. 이러한 신체에는 Filterexpression에서 정의 된 자체 Parameterexpression에 대한 참조가 포함됩니다.

새로운 ParameterExpression을 사용하기 위해 왼쪽 및 오른쪽 부분을 다시 작성하는 것입니다. 또는 원래 ParameterExpression을 전달합니다. 두 개의 parameterexpression이 동일한 매개 변수를 나타내는 것과 동일한 이름을 가지기 때문이 아닙니다.

다른 팁

이미 제안했듯이 여기 이 아주 좋은 (작동) 코드를 찾을 수 있습니다.

public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2)
{
    var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
    return Expression.Lambda<Func<T, bool>>(Expression.Or(expr1.Body, invokedExpr), expr1.Parameters);
}

당신은 당신의 요구에 적응할 수 있고 묶이지 않은 (IMHO)는 linq에 적용됩니다.

여기에 적절한 용어가 확실하지 않지만 기본적으로 표현식 매개 변수는 동일한 이름을 가지고 있어도 동일하지 않습니다.

그것은 의미합니다

var param1 = Expression.Parameter(typeof(T), "item");
var param2 = Expression.Parameter(typeof(T), "item");

param1 != param2

PARAM1 및 PARAM2는 표현식에 사용하는 경우 동일하지 않습니다.

이를 다루는 가장 좋은 방법은 표현식을 위해 하나의 매개 변수를 선발 한 다음 매개 변수가 필요한 모든 헬퍼 기능으로 전달하는 것입니다.

편집 : 또한 LINQ의 조항을 동적으로 구성하려는 경우 술어 빌더 시도.

검색 엔진 으로이 페이지를 찾아서 사용할 것입니다. Ben & Joe Albahari의 술집 구매자, 그것을 조심하십시오 엔티티 프레임 워크와 함께 작동하지 않습니다.

노력하다 이 고정 버전 대신에.

Fabrizio의 솔루션도 나에게도 발생했지만 LINQ 2 SQL 쿼리로 실행될 두 가지 표현을 결합하려고 시도한 이후 SQL 서버가 아닌 메모리에서 실행될 것이라고 생각했습니다.

LINQ-to-SQL은 호출이 람다 표현이라는 것을 인식하여 여전히 최적화 된 SQL을 생성한다는 것을 인식합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top