Apologies if the title is a little unclear but I'm not entirely sure what the correct terminology is.
I've written a custom LINQ provider to generate query strings against a search provider based on a lambda. This works fine as long as there's a 1:1 property:field mapping. However, I've now been asked to modify it so that when a certain properties are referenced, it generates an OR
and checks multiple fields.
So instead of function(x) x.CreatedDate = #1 Jan 2012#
generating ("CreatedDate" : "1 Jan 2012")
, it should now generate (("CreatedDate" : "1 Jan 2012" OR "CreatedOn" : "1 Jan 2012"))
I've annotated my entity so I can determine which alternate fields to check:
Public Class MyEntity
<AlsoKnownAs("CreatedOn")>
Public Property CreatedDate as Date
End Class
But where I'm struggling is how I can modify my expression visitor so that it generates the correct terms. Currently I do this...
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
I can detect the custom attributes at this point but I'm now down to the single member being evaluated, not the expression and I actually need to duplicate the parent node (the equals) a number of times.
How should I be approaching this?
To provide some more code, here's my
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