I\'m in the process of creating a more elaborate filtering system for this huge project of ours. One of the main predicates is being able to pass comparations through a string p
The hard part is actually returning the expression.
Translate strings into more structured constructions like enums and classes to define properties, operators and filters:
Enum Parameter
TotalCost
Required
End Enum
Enum Comparator
Less
More
Equals
End Enum
Class Criterion
Public ReadOnly Parameter As Parameter
Public ReadOnly Comparator As Comparator
Public ReadOnly Value As Double
Public Sub New(Parameter As Parameter, Comparator As Comparator, Value As Double)
Me.Parameter = Parameter
Me.Comparator = Comparator
Me.Value = Value
End Sub
End Class
Then a function to create expression is defined:
Function CreateExpression(Criteria As IEnumerable(Of Criterion)) As Expression(Of Func(Of Field, Boolean))
Dim FullExpression = PredicateBuilder.True(Of Field)()
For Each Criterion In Criteria
Dim Value = Criterion.Value
Dim TotalCostExpressions As New Dictionary(Of Comparator, Expression(Of Func(Of Field, Boolean))) From {
{Comparator.Less, Function(Field) Field.TotalCost < Value},
{Comparator.More, Function(Field) Field.TotalCost > Value},
{Comparator.Equals, Function(Field) Field.TotalCost = Value}
}
Dim RequiredExpressions As New Dictionary(Of Comparator, Expression(Of Func(Of Field, Boolean))) From {
{Comparator.Less, Function(Field) Field.Required < Value},
{Comparator.More, Function(Field) Field.Required > Value},
{Comparator.Equals, Function(Field) Field.Required = Value}
}
Dim Expressions As New Dictionary(Of Parameter, IDictionary(Of Comparator, Expression(Of Func(Of Field, Boolean)))) From {
{Parameter.TotalCost, TotalCostExpressions},
{Parameter.Required, RequiredExpressions}}
Dim Expression = Expressions(Criterion.Parameter)(Criterion.Comparator)
FullExpression = Expression.And(Expression)
Next
Return FullExpression
End Function
PredicateBuilder
taken here is needed to combine two expressions with AND
operator.
Usage:
Function Usage() As Integer
Dim Criteria = {
New Criterion(Parameter.TotalCost, Comparator.Less, 50),
New Criterion(Parameter.Required, Comparator.More, 5),
New Criterion(Parameter.Required, Comparator.Less, 10)}
Dim Expression = CreateExpression(Criteria)
End Function
It will create expression exactly like provided in an example
field => field.TotalCost < 50 && field.Required > 5 && field.Required < 10