2011-09-05 2 views
2

나는 사용자가 컬렉션에 "필터"를 채울 수있는 마녀가 있습니다. 그것은 매우 잘 작동동적 .NET 표현식에서 대괄호 사용하기

- Name  StartsWith 'a' 
    AND Population  >  10000 
    OR Population  <  1000 

내가 동적 PredicateBuilder를 사용하는 도시를 필터링 할 수있는 도시 컬렉션에 대한

AndOr Property Comparator Value 

"이 될 때까지, 말 : 사용자는 채우기에 약간의 열이 대괄호 "요구 사항이 나타났습니다.

위의 "쿼리"에서 알 수 있듯이 결과 모음에는
(Name.StartsWith'a' AND Population > 10000) OR (Population < 1000)의 도시가 있습니다. 표현 좀 괄호를 사용할 필요가
Name.StartsWith'a' AND (Population > 10000 OR (Population < 1000) 를 구축하기 위해

.

지금, 필터 그리드 열은 .NET 동적 표현 라이브러리의 일부 "그룹", "열기/CloseBracket는"거기에

AndOr LeftBracket Property Comparator Value RightBracket 

로 변경? 다른 방법으로 그것을 실현할 수 있습니까?

코드 것은 그들 사이의 "링크"행은

Private Function GetMyObjectsDataSource() As IQueryable(Of MyObject) 
    ' start without any filter, get it all ' 
    Dim predicate = PredicateBuilder.True(Of MyObject)() 
    Dim filterExpression As Expression(Of Func(Of MyObject, Boolean)) = predicate 

    For Each row In grdFilter.Rows 
    Dim rowExpression = GetExpressionFromRow(Of MyObject)(row) 
    Dim compOp As LogicalOperator = row.Cells(ColumnKeys.AndOr).Value 

    If compOp = LogicalOperator.Or Then 
     filterExpression = [Or](filterExpression, rowExpression) 
    Else 
     filterExpression = [And](filterExpression, rowExpression) 
    End If 
    Next row 

    Dim myObjects As List(Of MyObject) = Me._Container.GetMyObjects() 
    Dim result As IQueryable(Of MyObject) = 
    myObjects.AsQueryable().Where(filterExpression) 

    Return result 
End Function 
+0

나는 그것이'Block' 표현이라고 생각하지만, 확실하지 않습니다. – leppie

+0

@leppie : 유감스럽게도 내 경우에 블록 표현식을 사용하는 방법을 보지 못한다 ... – serhio

+1

@leppie : 블록 표현식은 여러 표현식을 그룹화하여 순서대로 (코드 블록과 유사하게) 그룹화하는 데 사용됩니다. (이제는 질문에 대한 의견을 말할 수있는 담당자가 충분합니다.) – user700390

답변

4

이 당신의 식 트리에서 중첩 된 하위 표현식을 사용하는 것입니다 다루는 가장 좋은 방법은 다음 하였다. 이것은 사용자의 입력을 해석하는 방식을 변경하는 것과 관련이 있습니다. 기본적으로 LeftBracket 요소가있을 때마다 현재 범위에서 다음 RightBracket 요소까지 하위 표현식을 재귀 적으로 작성합니다. 그런 다음 전체 하위 표현식을 현재 작업의 노드로 지정합니다.

질문의 코드 샘플을 검토 한 결과 "GetExpressionFromRow"함수를 사용하는 것이 가장 좋을 것으로 예상됩니다. 불행히도 "GetExpressionFromRow"는 질문에서 참조한 코드 라이브러리의 일부라고 생각하지 않습니다.

GetExpressionFromRow 및 종속성을 포함하도록 질문을 업데이트 할 수 있으면 더 자세히 조사하고보다 구체적인 대답을 시도 할 수 있습니다.

이 기술의 기본 알고리즘을 순환 하강 파서라고합니다. 여기에 몇 가지 일반 정보를보십시오 : http://en.wikipedia.org/wiki/Recursive_descent_parser

+2

@leppie (부적절한 평판으로 인해 질문에 언급 할 수없는 쪽지)로서 블록 표현식이 정답이 아닙니다.블록 표현식은 여러 표현식을 그룹화하여 순서대로 실행되도록합니다 (코드 블록과 유사 함) – user700390