2014-10-28 7 views
1

내 서비스에 전달 된 쿼리가 일련의 클래스로 직렬화되었습니다. 이 객체는 데이터를 무한 깊이로 AND/OR하는 것을 지원하는 트리 구조와 같은 조건을 정의합니다. 그런 다음 LinqToSQL을 사용하여이 클래스를 SQL 쿼리로 변환하지만 조건 (PredicateBuilder를 사용하여 정의 됨)은 무시됩니다!LinqToSQL에서 PredicateBuilder가 무시되었습니다.

PredicateBuilder는 분명한 해결책처럼 보입니다.이 재귀 함수는 IQueryable<Error> 대신 Expression<Func<Error,bool>>을 빌드하고 재귀 적으로 반복하고 AND/OR 조건을 적절히 추가합니다.

디버깅 할 때 다음과 같이 재귀 필터를 호출합니다. 필터를 올바르게 반환하는 재귀 함수를 볼 수 있습니다. 내 문제는 이러한 조건이 무시되고 출력 SQL에 표면화되지 않는다는 것입니다 (아래 참조). 왜 이럴 수 있니?

추가 정보가 필요하거나이 접근법이 효과가 있다고 생각하는 경우 알려 주시기 바랍니다.

if (hasConditions) 
{ 
    results.Where(RecursiveHandleFilterExpression(query.Criteria)); 
} 

는 2 개 LoggedOn 열에 통과 쿼리

SELECT [t2].[ErrorId], [t2].[OrganisationId], [t2].[Severity], [t2].[Source], [t2].[ExceptionMessage], [t2].[InnerExceptionMessage], [t2].[Details], [t2].[LoggedOn] 
FROM (
    SELECT [t1].[ErrorId], [t1].[OrganisationId], [t1].[Severity], [t1].[Source], [t1].[ExceptionMessage], [t1].[InnerExceptionMessage], [t1].[Details], [t1].[LoggedOn], [t1].[ROW_NUMBER] 
    FROM (
     SELECT ROW_NUMBER() OVER (ORDER BY [t0].[ErrorId], [t0].[OrganisationId], [t0].[Severity], [t0].[Source], [t0].[ExceptionMessage], [t0].[InnerExceptionMessage], [t0].[Details], [t0].[LoggedOn]) AS [ROW_NUMBER], [t0].[ErrorId], [t0].[OrganisationId], [t0].[Severity], [t0].[Source], [t0].[ExceptionMessage], [t0].[InnerExceptionMessage], [t0].[Details], [t0].[LoggedOn] 
     FROM [dbo].[Errors] AS [t0] 
     WHERE [t0].[OrganisationId] = @p0 
     ) AS [t1] 
    WHERE [t1].[ROW_NUMBER] BETWEEN @p1 + 1 AND @p1 + @p2 
    ) AS [t2] 
ORDER BY [t2].[ROW_NUMBER] 
-- @p0: Input UniqueIdentifier (Size = -1; Prec = 0; Scale = 0) [f311d7f3-3755-e411-940e-00155d0c0c4b] 
-- @p1: Input Int (Size = -1; Prec = 0; Scale = 0) [0] 
-- @p2: Input Int (Size = -1; Prec = 0; Scale = 0) [51] 
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 4.0.30319.17929 
+1

당신은 결과 ->'results = results.Where (RecursiveHandleFilterExpression (query.Criteria));'에 다시 할당하는 것을 잊어 버린 것 같아요. – Silvermind

답변

3

AndOr 누락 DataContext.Log 속성을 통해 얻어진 술어

private Expression<Func<Error, bool>> RecursiveHandleFilterExpression(FilterExpression filterExpression) 
{ 
    // if anding, start with true Ors start with false 
    Expression<Func<Error, bool>> predicate; 
    if (filterExpression.FilterOperator == LogicalOperator.And) 
    { 
     predicate = PredicateBuilder.True<Error>(); 
    } 
    else 
    { 
     predicate = PredicateBuilder.False<Error>(); 
    } 

    // apply conditions 
    foreach (ConditionExpression condition in filterExpression.Conditions) 
    { 
     if (filterExpression.FilterOperator == LogicalOperator.And) 
     { 
      predicate.And(ApplyCondition(condition)); 
     } 
     else 
     { 
      predicate.Or(ApplyCondition(condition)); 
     } 
    } 

    // apply child filters 
    foreach (FilterExpression expression in filterExpression.Filters) 
    { 
     if (filterExpression.FilterOperator == LogicalOperator.And) 
     { 
      predicate.And(RecursiveHandleFilterExpression(expression)); 
     } 
     else 
     { 
      predicate.Or(RecursiveHandleFilterExpression(expression)); 
     } 
    } 

    return predicate; 
} 

생성 SQL를 추가하는 기능, 인 메소드는 표현식을 변형시키지 않습니다. 문제의 연산을 나타내는 식을 반환합니다. 코드에서 반환 값을 무시합니다.