private IFilterNode ParseComparisonExpression(IFilterNode firstArgument) { if (Is(FilterTokenType.ComparisonOperator)) { FilterToken token = Expect(FilterTokenType.ComparisonOperator); IFilterNode filterNode = PrimaryExpression(); return(new ComparisonNode { First = firstArgument, FilterOperator = token.ToFilterOperator(), Second = filterNode }); } else { FilterToken token = Expect(FilterTokenType.Function); var functionNode = new FunctionNode { FilterOperator = token.ToFilterOperator() }; functionNode.Arguments.Add(firstArgument); functionNode.Arguments.Add(PrimaryExpression()); return(functionNode); } }
public static async Task <IFilterNode <TResultFilter> > MapAsync <TFilter, TResultFilter>( this IFilterNode <TFilter> filter, Func <TFilter, Task <TResultFilter> > mapFunc) where TFilter : IFilter where TResultFilter : IFilter { switch (filter) { case ICombinationFilterNode <TFilter> combinationFilter: var innerNodesTasks = combinationFilter.Nodes.Select(f => f.MapAsync(mapFunc)); var innerNodes = await Task.WhenAll(innerNodesTasks).ConfigureAwait(false); return(innerNodes.Combine(combinationFilter.Operator)); case IInvertedFilterNode <TFilter> invertedFilter: var innerNodeToInvert = await invertedFilter.NodeToInvert.MapAsync(mapFunc).ConfigureAwait(false); return(innerNodeToInvert.Invert()); case ILeafFilterNode <TFilter> leafFilter: return((await mapFunc(leafFilter.Filter).ConfigureAwait(false)).ToLeafFilterNode()); default: throw new InvalidOperationException($"Unhandled {nameof(filter)} of type: {filter.GetType()}"); } }
private static Func <TItemToTest, bool> GetPredicate <TFilter, TItemToTest>( this IFilterNode <TFilter> filterNode, Func <TFilter, Func <TItemToTest, bool> > itemPredicate) => filterNode.Aggregate( Combine, Invert, leafFilterNode => itemPredicate(leafFilterNode.Filter));
public static async Task <IFilterNode <TResultLeafNode> > MapAsync <TLeafNode, TResultLeafNode>( this IFilterNode <TLeafNode> filter, Func <TLeafNode, Task <TResultLeafNode> > mapFunc) where TLeafNode : class, ILeafFilterNode where TResultLeafNode : class, ILeafFilterNode <TResultLeafNode> { switch (filter) { case ICombinationFilterNode <TLeafNode> combinationFilter: var innerFilterTasks = combinationFilter.Filters.Select(f => f.MapAsync(mapFunc)); var innerFilters = await Task.WhenAll(innerFilterTasks); return(new CombinationFilter <TResultLeafNode>(innerFilters, combinationFilter.Operator)); case IInvertedFilter <TLeafNode> invertedFilter: var innerFilter = await invertedFilter.FilterToInvert.MapAsync(mapFunc); return(new InvertedFilter <TResultLeafNode>(innerFilter)); case TLeafNode leafFilter: return(await mapFunc(leafFilter)); default: throw new InvalidOperationException($"Unhandled {nameof(filter)} of type: {filter.GetType()}"); } }
private IFilterNode ParseComparisonExpression(IFilterNode firstArgument) { if (Is(FilterTokenType.ComparisonOperator)) { FilterToken comparison = Expect(FilterTokenType.ComparisonOperator); IFilterNode secondArgument = PrimaryExpression(); return(new ComparisonNode { First = firstArgument, FilterOperator = comparison.ToFilterOperator(), Second = secondArgument }); } else if (IsIn(FilterTokenType.Function)) { return(ParseFunctionExpression(firstArgument)); } FilterToken function = Expect(FilterTokenType.Function); var functionNode = new FunctionNode { FilterOperator = function.ToFilterOperator() }; functionNode.Arguments.Add(firstArgument); functionNode.Arguments.Add(PrimaryExpression()); return(functionNode); }
public static string GetGroupCriteria(IFilterNode groupNode) { string result = ""; if (groupNode == null || !groupNode.IsGroup) return ""; foreach (var child in groupNode.Children) { string childStatement = ""; if (!child.IsGroup) { childStatement = GetFilterItemStatement(child); } else { childStatement = GetGroupCriteria(child); } if (childStatement != "") { result += groupNode.ChildrenRelation + childStatement; } } if (result != "") result = " (" + result.Substring(groupNode.ChildrenRelation.Length) + ") "; return result; }
/// <summary> /// Removes redundancies in a filter to give simplest expression /// </summary> /// <typeparam name="TLeafNode"></typeparam> /// <param name="filter"></param> /// <returns></returns> public static IFilterNode <TLeafNode> Collapse <TLeafNode>(this IFilterNode <TLeafNode> filter) where TLeafNode : class, ILeafFilterNode { return(filter.Match( combinationFilter => { return combinationFilter.Operator.Match( () => { var collapsedInnerFilters = combinationFilter.Filters.Select(f => f.Collapse()) .ToList(); if (collapsedInnerFilters.Any(f => f.Equals(FilterNode <TLeafNode> .False))) { return FilterNode <TLeafNode> .False; } var nonTrivialFilters = collapsedInnerFilters.Where(f => !f.Equals(FilterNode <TLeafNode> .True)); var collapsedCombinationFilter = new CombinationFilter <TLeafNode>(nonTrivialFilters, combinationFilter.Operator); return collapsedCombinationFilter.Filters.Count == 1 ? collapsedCombinationFilter.Filters.Single() : collapsedCombinationFilter; }, () => { var collapsedInnerFilters = combinationFilter.Filters.Select(f => f.Collapse()) .ToList(); if (collapsedInnerFilters.Any(f => f.Equals(FilterNode <TLeafNode> .True))) { return FilterNode <TLeafNode> .True; } var nonTrivialFilters = collapsedInnerFilters.Where(f => !f.Equals(FilterNode <TLeafNode> .False)); var collapsedCombinationFilter = new CombinationFilter <TLeafNode>(nonTrivialFilters, combinationFilter.Operator); return collapsedCombinationFilter.Filters.Count == 1 ? collapsedCombinationFilter.Filters.Single() : collapsedCombinationFilter; }); }, invertedFilter => { var collapsedInnerFilter = invertedFilter.FilterToInvert.Collapse(); // If we have NOT(TRUE) then return FALSE or if we have NOT(FALSE) return TRUE. if (collapsedInnerFilter is ICombinationFilterNode <TLeafNode> combinationInner && combinationInner.Filters.Count == 0) { return combinationInner.Operator.Match(() => FilterNode <TLeafNode> .False, () => FilterNode <TLeafNode> .True); } // If we have NOT(NOT(f)) just return f if (collapsedInnerFilter is IInvertedFilter <TLeafNode> invertedInner) { return invertedInner.FilterToInvert; } return new InvertedFilter <TLeafNode>(collapsedInnerFilter); }, leafFilter => (IFilterNode <TLeafNode>)leafFilter)); // TODO: Figure out a way to remove this evil cast? }
/// <summary> /// Executa o parse na expressão com uma estrutura aninhada. /// </summary> /// <returns></returns> private IFilterNode ParseNestedExpression() { this.Expect(FilterTokenType.LeftParenthesis); IFilterNode node = this.Expression(); this.Expect(FilterTokenType.RightParenthesis); return(node); }
private IFilterNode ParseNestedExpression() { Expect(FilterTokenType.LeftParenthesis); IFilterNode filterNode = Expression(); Expect(FilterTokenType.RightParenthesis); return(filterNode); }
public static bool IsMatch <TFilter, TItemToTest>( this IFilterNode <TFilter> filter, TItemToTest item) where TFilter : IFilter <TItemToTest> { var predicate = filter.GetPredicate <TFilter, TItemToTest>(); return(predicate(item)); }
public static bool IsMatch <TLeafNode, TItemToTest>( this IFilterNode <TLeafNode> filter, TItemToTest item) where TLeafNode : class, ILeafFilterNode, IRealisableLeafFilterNode <TItemToTest> { var predicate = filter.GetPredicate <TLeafNode, TItemToTest>(); return(predicate(item)); }
/// <summary> /// Executa o parse na expressão com a estrutura OR. /// </summary> /// <param name="firstArgument"></param> /// <returns></returns> private IFilterNode ParseOrExpression(IFilterNode firstArgument) { this.Expect(FilterTokenType.Or); IFilterNode node = this.OrExpression(); return(new OrNode { First = firstArgument, Second = node }); }
public override bool Equals(IFilterNode other) { if (ReferenceEquals(this, other)) { return(true); } return(other is ILeafFilterNode leafOther && Filter.Equals(leafOther.Filter)); }
private IFilterNode AndExpression() { IFilterNode firstArgument = ComparisonExpression(); if (Is(FilterTokenType.And)) { return(ParseAndExpression(firstArgument)); } return(firstArgument); }
private IFilterNode ComparisonExpression() { IFilterNode firstArgument = PrimaryExpression(); if (Is(FilterTokenType.ComparisonOperator) || Is(FilterTokenType.Function)) { return(ParseComparisonExpression(firstArgument)); } return(firstArgument); }
// TODO: Maybe this can be made private/internal? public static Func <TItemToTest, bool> GetPredicate <TLeafNode, TItemToTest>( this IFilterNode <TLeafNode> filter, Func <TLeafNode, Func <TItemToTest, bool> > itemPredicate) where TLeafNode : class, ILeafFilterNode { return(filter.Aggregate( Combine, Invert, itemPredicate)); }
/// <summary> /// Executa o parse sobre a expressão AND. /// </summary> /// <param name="firstArgument"></param> /// <returns></returns> private IFilterNode ParseAndExpression(IFilterNode firstArgument) { Expect(FilterTokenType.And); var node = ComparisonExpression(); return(new AndNode { First = firstArgument, Second = node }); }
private IFilterNode ParseOrExpression(IFilterNode firstArgument) { Expect(FilterTokenType.Or); IFilterNode secondArgument = OrExpression(); return(new OrNode { First = firstArgument, Second = secondArgument }); }
public override bool Equals(IFilterNode other) { if (ReferenceEquals(this, other)) { return(true); } return(other is ICombinationFilterNode <TLeafNode> combinationOther && Filters.SequenceEqual(combinationOther.Filters) && Operator == combinationOther.Operator); }
/// <summary> /// Removes non-matching nodes and replaces them with <see cref="FilterNode{TFilter}.True"/> /// </summary> /// <typeparam name="TFilter"></typeparam> /// <param name="filter"></param> /// <param name="predicate"></param> /// <returns></returns> public static IFilterNode <TFilter> Where <TFilter>( this IFilterNode <TFilter> filter, Func <TFilter, bool> predicate) where TFilter : IFilter => filter.Bind <TFilter>(leafFilter => { if (predicate(leafFilter)) { return(leafFilter.ToLeafFilterNode()); } return(FilterNode <TFilter> .True); });
/// <summary> /// 'Relaxes' a filter by relaxing each leaf of the filter according to <see cref="relaxFilterFunc"/>, or restricting /// inversions according to <see cref="restrictFilterFunc"/>. /// /// This is the inverse operation of <see cref="Restrict{TFilter}"/>. /// </summary> /// <param name="filter"></param> /// <param name="relaxFilterFunc"> /// A function which takes a leaf node and relaxes it /// </param> /// <param name="restrictFilterFunc"> /// A function which takes a leaf node and restricts it (i.e. the inverse operation of relax). /// </param> /// <returns></returns> public static IFilterNode <TFilter> Relax <TFilter>( this IFilterNode <TFilter> filter, Func <TFilter, IFilterNode <TFilter> > relaxFilterFunc, Func <TFilter, IFilterNode <TFilter> > restrictFilterFunc) where TFilter : IFilter => filter.Match( combinationFilterNode => { var innerNodes = combinationFilterNode.Nodes.Select(f => Relax(f, relaxFilterFunc, restrictFilterFunc)); return(innerNodes.Combine(combinationFilterNode.Operator)); }, invertedFilterNode => Restrict(invertedFilterNode.NodeToInvert, restrictFilterFunc, relaxFilterFunc).Invert(), leafFilterNode => relaxFilterFunc(leafFilterNode.Filter)) .Collapse();
public bool IsEquivalentTo(IFilterNode other) { if (Equals(this, other)) { return(true); } if (!IsCollapsed) { return(Collapse().IsEquivalentTo(other)); } return(IsEquivalentToInternal(other.Collapse())); }
public override bool Equals(IFilterNode other) { if (ReferenceEquals(this, other)) { return(true); } if (!(other is ICombinationFilterNode combinationOther) || Operator != combinationOther.Operator) { return(false); } return(Nodes.SequenceEqual(combinationOther.Nodes)); }
public static IList <IFilterDescriptor> Create(string input) { IList <IFilterDescriptor> result = new List <IFilterDescriptor>(); FilterParser parser = new FilterParser(input); IFilterNode filterNode = parser.Parse(); if (filterNode == null) { return(result); } FilterNodeVisitor visitor = new FilterNodeVisitor(); filterNode.Accept(visitor); result.Add(visitor.Result); return(result); }
/// <summary> /// Recupera a expressão OR. /// </summary> /// <returns></returns> private IFilterNode OrExpression() { IFilterNode firstArgument = this.AndExpression(); if (Is(FilterTokenType.Or)) { return(ParseOrExpression(firstArgument)); } if (Is(FilterTokenType.And)) { Expect(FilterTokenType.And); return(new AndNode { First = firstArgument, Second = OrExpression() }); } return(firstArgument); }
/// <summary> /// 'Relaxes' a filter by relaxing each leaf of the filter according to <see cref="relaxFilterFunc"/>, or restricting /// inversions according to <see cref="restrictFilterFunc"/>. /// /// This is the inverse operation of <see cref="RestrictAsync{T}"/>. /// </summary> /// <param name="filter"></param> /// <param name="relaxFilterFunc"> /// A function which takes a leaf node and relaxes it /// </param> /// <param name="restrictFilterFunc"> /// A function which takes a leaf node and restricts it (i.e. the inverse operation of relax). /// </param> /// <returns></returns> public static async Task <IFilterNode <TFilter> > RelaxAsync <TFilter>( this IFilterNode <TFilter> filter, Func <TFilter, Task <IFilterNode <TFilter> > > relaxFilterFunc, Func <TFilter, Task <IFilterNode <TFilter> > > restrictFilterFunc) where TFilter : IFilter { var result = await filter.Match <Task <IFilterNode <TFilter> > >( async combinationFilterNode => { var innerFilterNodeTasks = combinationFilterNode.Nodes.Select(f => RelaxAsync(f, relaxFilterFunc, restrictFilterFunc)); var innerFilterNodes = await Task.WhenAll(innerFilterNodeTasks).ConfigureAwait(false); return(innerFilterNodes.Combine(combinationFilterNode.Operator)); }, async invertedFilterNode => (await RestrictAsync(invertedFilterNode.NodeToInvert, restrictFilterFunc, relaxFilterFunc).ConfigureAwait(false)).Invert(), leafFilterNode => relaxFilterFunc(leafFilterNode.Filter)) .ConfigureAwait(false); return(result.Collapse()); }
public static async Task <TResult> MatchAsync <TFilter, TResult>( this IFilterNode <TFilter> node, Func <ICombinationFilterNode <TFilter>, TResult> combine, Func <IInvertedFilterNode <TFilter>, TResult> invert, Func <ILeafFilterNode <TFilter>, Task <TResult> > transform) { switch (node) { case ICombinationFilterNode <TFilter> combinationNode: return(combine(combinationNode)); case IInvertedFilterNode <TFilter> invertedNode: return(invert(invertedNode)); case ILeafFilterNode <TFilter> leafNode: return(await transform(leafNode).ConfigureAwait(false)); default: throw new InvalidOperationException($"Unhandled {nameof(node)} of type: {node.GetType()}"); } }
/// <summary> /// Computes the filter that includes only leaf filters that satisfy the given predicate. /// The result is guaranteed to be less than or equal in restrictiveness to the original. /// This means that it will never filter out results that the original filter would not have /// filtered. /// </summary> /// <param name="node"></param> /// <param name="predicate"></param> /// <returns></returns> public static IFilterNode <TFilter> GetPartial <TFilter>(this IFilterNode <TFilter> node, Func <TFilter, bool> predicate) where TFilter : IFilter => node.Relax( filter => { if (predicate(filter)) { return(filter.ToLeafFilterNode()); } return(FilterNode <TFilter> .True); }, filter => { if (predicate(filter)) { return(filter.ToLeafFilterNode()); } return(FilterNode <TFilter> .False); });
/// <summary> /// Executa o parser a expressão de comparação. /// </summary> /// <param name="firstArgument"></param> /// <returns></returns> private IFilterNode ParseComparisonExpression(IFilterNode firstArgument) { if (this.Is(FilterTokenType.ComparisonOperator)) { FilterToken token = this.Expect(FilterTokenType.ComparisonOperator); IFilterNode node = this.PrimaryExpression(); return(new ComparisonNode { First = firstArgument, FilterOperator = token.ToFilterOperator(), Second = node }); } FilterToken token2 = this.Expect(FilterTokenType.Function); FunctionNode node3 = new FunctionNode { FilterOperator = token2.ToFilterOperator() }; node3.Arguments.Add(firstArgument); node3.Arguments.Add(this.PrimaryExpression()); return(node3); }
/// <summary> /// Computes the filter that includes only leaf filters that satisfy the given predicate. /// The result is guaranteed to be less than or equal in restrictiveness to the original. /// This means that it will never filter out results that the original filter would not have /// filtered. /// </summary> /// <param name="filter"></param> /// <param name="predicate"></param> /// <returns></returns> public static IFilterNode <TLeafNode> GetPartial <TLeafNode>(this IFilterNode <TLeafNode> filter, Func <TLeafNode, bool> predicate) where TLeafNode : class, ILeafFilterNode { (IFilterNode <TLeafNode> Result, IFilterNode <TLeafNode> ResultToInvert) GetPartialTuple(IFilterNode <TLeafNode> inner) { return(inner.Match( combinationFilter => { var innerPartialTuples = combinationFilter.Filters.Select(GetPartialTuple) .ToList(); return ( Result: new CombinationFilter <TLeafNode>(innerPartialTuples.Select(tuple => tuple.Result), combinationFilter.Operator), ResultToInvert: new CombinationFilter <TLeafNode>(innerPartialTuples.Select(tuple => tuple.ResultToInvert), combinationFilter.Operator)); }, invertedFilter => { var partialTuple = GetPartialTuple(invertedFilter.FilterToInvert); return ( Result: new InvertedFilter <TLeafNode>(partialTuple.ResultToInvert), ResultToInvert: new InvertedFilter <TLeafNode>(partialTuple.Result)); }, leafFilter => { if (predicate(leafFilter)) { return (Result: (IFilterNode <TLeafNode>)leafFilter, ResultToInvert: (IFilterNode <TLeafNode>)leafFilter); } // If we are here, it means we're going to remove the leaf filter. For a result that won't be inverted, // return true - the least restrictive. For a result that will be inverted, return false - the most restrictive. // The final result can not be more restrictive than the original. return (Result: FilterNode <TLeafNode> .True, ResultToInvert: FilterNode <TLeafNode> .False); })); } return(GetPartialTuple(filter) .Result .Collapse()); }
public static async Task <TResult> MatchAsync <TLeafNode, TResult>( this IFilterNode <TLeafNode> filter, Func <ICombinationFilterNode <TLeafNode>, TResult> combine, Func <IInvertedFilter <TLeafNode>, TResult> invert, Func <TLeafNode, Task <TResult> > transform) where TLeafNode : class, ILeafFilterNode { switch (filter) { case ICombinationFilterNode <TLeafNode> combinationFilter: return(combine(combinationFilter)); case IInvertedFilter <TLeafNode> invertedFilter: return(invert(invertedFilter)); case TLeafNode leafFilter: return(await transform(leafFilter)); default: throw new InvalidOperationException($"Unhandled {nameof(filter)} of type: {filter.GetType()}"); } }
private IFilterNode ParseOrExpression(IFilterNode firstArgument) { Expect(FilterTokenType.Or); IFilterNode secondArgument = OrExpression(); return new OrNode { First = firstArgument, Second = secondArgument }; }
private IFilterNode ParseComparisonExpression(IFilterNode firstArgument) { if (Is(FilterTokenType.ComparisonOperator)) { FilterToken comparison = Expect(FilterTokenType.ComparisonOperator); IFilterNode secondArgument = PrimaryExpression(); return new ComparisonNode { First = firstArgument, FilterOperator = comparison.ToFilterOperator(), Second = secondArgument }; } FilterToken function = Expect(FilterTokenType.Function); var functionNode = new FunctionNode { FilterOperator = function.ToFilterOperator() }; functionNode.Arguments.Add(firstArgument); functionNode.Arguments.Add(PrimaryExpression()); return functionNode; }
private IFilterNode ParseAndExpression(IFilterNode firstArgument) { Expect(FilterTokenType.And); IFilterNode secondArgument = ComparisonExpression(); return new AndNode { First = firstArgument, Second = secondArgument }; }
void ResetValueByAction(IFilterNode node) { if (node.Type == TypeCode.Boolean) { node.Value = true; } else { node.Value = null; node.Scope.From = null; node.Scope.To = null; } }
void ResetValueByFieldName(IFilterNode node) { if (node.Type == TypeCode.Boolean) { node.Value = true; node.Action = ActionType.IsTrue; } else { node.Value = null; node.Scope.From = null; node.Scope.To = null; node.Action = ActionType.Equal; } }
int SetInsertingIndex(IFilterNode node, ref int index) { foreach (IFilterNode child in node.Children) { index++; if (child.Children.Count > 0) SetInsertingIndex(child, ref index); } return index; }
private IFilterNode ParseComparisonExpression(IFilterNode firstArgument) { FilterToken comparison = Expect(FilterTokenType.ComparisonOperator); IFilterNode secondArgument = PrimaryExpression(); return new ComparisonNode { First = firstArgument, FilterOperator = comparison.ToFilterOperator(), Second = secondArgument }; }
static string GetFilterItemStatement(IFilterNode node) { if (node.Action == ActionType.IsNull) { return " [" + node.FieldName + "] IS NULL "; } else if (node.Action == ActionType.NotNull) { return " [" + node.FieldName + "] IS NOT NULL "; } else if (node.Action == ActionType.IsTrue) { return " [" + node.FieldName + "] = true "; } else if (node.Action == ActionType.IsFalse) { return " [" + node.FieldName + "] = false "; } else if (node.Action == ActionType.Between) { var result = ""; if (HasValue(node.Scope.From)) { result += " [" + node.FieldName + "] >= " + FormatValue(node.Scope.From); } if (HasValue(node.Scope.To)) { if (result.IsNotEmpty()) result += " And "; result += "[" + node.FieldName + "] <= " + FormatValue(node.Scope.To, true); } if (result == "") return ""; return " (" + result + ") "; } else if (node.Action == ActionType.NotBetween) { var result = ""; if (HasValue(node.Scope.From)) { result += " [" + node.FieldName + "] < " + FormatValue(node.Scope.From); } if (HasValue(node.Scope.To)) { if (result.IsNotEmpty()) result += " Or "; result += "[" + node.FieldName + "] > " + FormatValue(node.Scope.To, true); } if (result == "") return ""; return " (" + result + ") "; } else if (node.Value.ToSafeString() == "") return ""; else if (node.Action == ActionType.Equal) { if (node.Type == TypeCode.DateTime) { var result = ""; if (HasValue(node.Value)) { result += " [" + node.FieldName + "] >= " + FormatValue(node.Value); result += " And [" + node.FieldName + "] <= " + FormatValue(node.Value, true); } if (result == "") return ""; return " (" + result + ") "; } else { return " [" + node.FieldName + "] = " + FormatValue(node.Value) + " ";//node.Value.ToString() + " "; } } else if (node.Action == ActionType.NotEqual) { if (node.Type == TypeCode.DateTime) { var result = ""; if (HasValue(node.Value)) { result += " [" + node.FieldName + "] <= " + FormatValue(node.Value); result += " Or [" + node.FieldName + "] >= " + FormatValue(node.Value, true); } if (result == "") return ""; return " (" + result + ") "; } else { return " [" + node.FieldName + "] != " + FormatValue(node.Value) + " ";//node.Value.ToString() + "' "; } } else if (node.Action == ActionType.EndWith) { return " [" + node.FieldName + "] Like " + "'%" + node.Value.ToString() + "' "; } else if (node.Action == ActionType.Contain) { return " [" + node.FieldName + "] Like " + "'%" + node.Value.ToString() + "%' "; } else if (node.Action == ActionType.BeginWith) { return " [" + node.FieldName + "] Like " + "'" + node.Value.ToString() + "%' "; } else if (node.Action == ActionType.NotContain) { return " [" + node.FieldName + "] Not Like " + "'%" + node.Value.ToString() + "%' "; } else if (node.Action == ActionType.Lesser) { return " [" + node.FieldName + "] < " + FormatValue(node.Value) + " ";//node.Value.ToString(); } else if (node.Action == ActionType.LesserOrEqual) { return " [" + node.FieldName + "] <= " + FormatValue(node.Value) + " ";//node.Value.ToString(); } else if (node.Action == ActionType.Greater) { return " [" + node.FieldName + "] > " + FormatValue(node.Value) + " ";//node.Value.ToString(); } else if (node.Action == ActionType.GreaterOrEqual) { return " [" + node.FieldName + "] >= " + FormatValue(node.Value) + " ";//node.Value.ToString(); } return ""; }