2

タイトルが少し不明確な場合はお詫びしますが、正しい用語が何であるか完全にはわかりません。

ラムダに基づいて検索プロバイダーに対してクエリ文字列を生成するカスタムLINQプロバイダーを作成しました。これは、1:1のproperty:fieldマッピングがある限り正常に機能します。ただし、特定のプロパティが参照されるときに、を生成してOR複数のフィールドをチェックするように変更するように求められました。

したがって、を生成する代わりに、をfunction(x) x.CreatedDate = #1 Jan 2012#生成("CreatedDate" : "1 Jan 2012")する必要があります(("CreatedDate" : "1 Jan 2012" OR "CreatedOn" : "1 Jan 2012"))

チェックする代替フィールドを決定できるように、エンティティに注釈を付けました。

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

しかし、私が苦労しているのは、正しい用語を生成するように式の訪問者を変更する方法です。現在私はこれをしています...

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
4

1 に答える 1

1

これの影響を受ける式ビジターのコードを変更する必要があるように思えます(boolと評価されるもの):

  • VisitBinaryExpressionいつExpressionですかExpression.Equal
  • フィールドがブール値に評価されている場合は、fieldnameOR `fieldname2' を置き換えることができます (解決策の詳細はわかりません)。

あなたが投稿したコードから、私は次のようなことができます:

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

次にVisitEqual、エイリアスに基づいて OR 式を作成する必要があります。

于 2012-09-13T10:13:15.273 に答える