2012-09-13 2 views
2

제목이 약간 불분명하지만 정확한 용어가 무엇인지 잘 모르는 경우 사과드립니다.Linq 표현 방문자 확장 멤버 비교 여러 회원 비교

람다를 기반으로 검색 공급자에 대해 쿼리 문자열을 생성하기 위해 사용자 지정 LINQ 공급자를 작성했습니다. 1 : 1 속성 : 필드 매핑이있는 한 잘 작동합니다. 그러나 특정 속성을 참조 할 때 OR을 생성하고 여러 필드를 검사하도록 수정할 것을 요청 받았습니다.

Public Class MyEntity 
    <AlsoKnownAs("CreatedOn")> 
    Public Property CreatedDate as Date 
End Class 

을하지만 사투를 벌인거야 곳입니다 ("CreatedDate" : "1 Jan 2012")를 생성

그래서 대신 function(x) x.CreatedDate = #1 Jan 2012#, 지금 내 법인을 주석 한 (("CreatedDate" : "1 Jan 2012" OR "CreatedOn" : "1 Jan 2012"))

그래서 확인하기 위해 다른 어떤 분야 확인할 수 있습니다 생성해야 표현 방문자를 수정하여 올바른 용어를 생성 할 수있는 방법. 현재 내가 이렇게 ...

Protected Overrides Function VisitMember(m As MemberExpression) As Expression 
    If m.Expression IsNot Nothing AndAlso m.Expression.NodeType = ExpressionType.Parameter Then 
     sb.Append("""") 
     sb.Append(m.Member.Name) 
     sb.Append("""") 
     Return m 
    End If 
    Throw New NotSupportedException(String.Format("The member '{0}' is not supported", m.Member.Name)) 
End Function 

나는 사용자 지정이 시점에서 속성을하지만,하지 발현을 평가하고 아래로 단일 구성원 지금 그리고 난 실제로합니다 (부모 노드를 복제 할 필요가 감지 할 수 있습니다 같음).

어떻게 접근해야합니까?

여기 그것은 당신이에 의해 영향을받는 식 방문자에 대한 코드를 수정할 필요가 날 것으로 보인다

Protected Overrides Function VisitBinary(b As BinaryExpression) As Expression 
    Select Case b.NodeType 
      .... 
     Case ExpressionType.Equal 
      If b.Left.NodeType = ExpressionType.Call AndAlso 
       DirectCast(b.Left, MethodCallExpression).Method.DeclaringType = GetType(Microsoft.VisualBasic.CompilerServices.Operators) AndAlso 
       DirectCast(b.Left, MethodCallExpression).Method.Name = "CompareString" Then 
       'Cope with the the VB Pain-In-The-Ass string comparison handling 
       Me.Visit(b.Left) 
      Else 
       'Carry on 
       Me.Visit(b.Left) 
       sb.Append(" : ") 
       Me.Visit(b.Right) 
      End If 
      Exit Select 
+0

방문자가 단항/이진 표현식을 실제로 수정하지 않고도 할 수 있는지 궁금합니다 ...이 방법을 따르고 싶지 않으십니까? – Bartosz

+0

@Bartosz 내가 올바르게 이해한다면 실제적인 이의는 없지만 VB가 문자열 비교를 처리하는 방식 때문에 문제가 발생했습니다 ([this Q] (http://stackoverflow.com/questions/12197569) 참조). ,하지만 당신이 그것을 할 수있는 편리한 방법을 볼 수 있다면, 나는 흥미가있을거야 – Basic

+0

그냥 MethodDeclaringType 및 메서드 이름을 확인하고 다음과 같은 몇 가지 표현식을 호출하여 특별한 경우가 내 마음에오고있다 인수에서 만든 인수 ('Expression.Create (...)') – Bartosz

답변

1

(bool로하는 평가 그들 내가 가정) 제의, 좀 더 코드를 제공합니다 :

  • VisitBinaryExpressionExpressionExpression.Equal
  • 당신의 필드가 bool에 위해 평가되고있는 경우 일 때, 당신은 fieldname 또는`fieldname2 '를 대체 할 수 있습니다 (I 몰라 솔루션의 특성). 당신이 게시 한 코드에서

, 내가 좋아하는 뭔가를 할 수있는 : 난 그냥 새로운 표현을 만들 것 VB-비교 케이스 *, 그리고 별칭을 처리 할 다른 방문자와 함께 방문

expr = Expression.Equal(left, right) // left and right I would fetch from MethodCallExpression Arguments property 
VisitEqual(expr) 

다음으로 VisitEqual은 별칭을 기반으로하는 OR 식을 작성해야합니다.

+0

내 "쿼리 문자열"은 실제로 트리이므로 구조가 너무 많은 문제를 나타내서는 안됩니다.내 이진 비교 예제를 게시하여 작업중인 것을 볼 수 있습니다. – Basic

+0

감사합니다. 유망한 것 같아서 그걸 가지고 놀게 해주세요. – Basic

+0

내 대답은 더 자세히 설명 할 수 없어요. 거의 없습니다. VB 지식, 그리고 몇 년 전에 단 한 번만 사용자 지정 쿼리 공급자와 놀고 있었는데 ... – Bartosz