如果标题有点不清楚,我很抱歉,但我不完全确定正确的术语是什么。
我已经编写了一个自定义LINQ提供程序,用于针对基于lambda的搜索提供程序生成查询字符串。只要有1:1的特性:字段映射,这就可以很好地工作。但是,我现在被要求修改它,以便在引用某个属性时,它生成一个OR
并检查多个字段。
因此,现在应该生成(("CreatedDate" : "1 Jan 2012" OR "CreatedOn" : "1 Jan 2012"))
,而不是function(x) x.CreatedDate = #1 Jan 2012#
生成("CreatedDate" : "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
在这一点上,我可以检测到自定义属性,但现在我只关注正在评估的单个成员,而不是表达式,而且我实际上需要多次复制父节点(equals)。
我该如何处理?
为了提供更多的代码,这里是我的
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
在我看来,你需要修改受此影响的表达式访问者的代码(我认为那些评估为bool的访问者):
Expression
为Expression.Equal
时的VisitBinaryExpression
- 当您的字段被评估为bool时,您可以用
fieldname
或`fieldname2'代替(我不知道您的解决方案的细节)
根据你发布的代码,我可以做如下操作:*对于VB比较的情况,我只需要创建一个新的Expression,并与另一个处理别名的访问者一起访问它:
expr = Expression.Equal(left, right) // left and right I would fetch from MethodCallExpression Arguments property
VisitEqual(expr)
则CCD_ 9应当仅基于别名来构建OR表达式。