Linq表达访问者扩展成员比较多个成员比较

时间:2012-09-13 09:44:49

标签: .net linq lambda

道歉,如果标题有点不清楚,但我不完全确定正确的术语是什么。

我编写了一个自定义LINQ提供程序,用于根据lambda为搜索提供程序生成查询字符串。只要有1:1属性:字段映射,这样就可以正常工作。但是,我现在被要求修改它,以便在引用某些属性时,它会生成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

1 个答案:

答案 0 :(得分:1)

在我看来,你需要修改受此影响的表达式访问者的代码(那些评估为我假设的bool):

    VisitBinaryExpressionExpression 时,
  • Expression.Equal
  • 当您的字段被评估为bool时,您可以替换fieldname或`fieldname2'(我不知道您的解决方案的细节)。

根据您发布的代码,我可以执行以下操作: *对于VB比较案例,我只想创建新的Expression,并与另一个处理别名的访问者一起访问它:

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

然后VisitEqual应该根据别名构建OR表达式。