private static ConstantExpression GetScalarValue(FilterValue value, Type type) { var converter = TypeDescriptor.GetConverter(type); if (converter == null) { throw new InvalidOperationException($"Couldn't find type converter for type '{type.Name}'."); } return(Expression.Constant(converter.ConvertFromString(value.Value))); }
public override Expression Visit(Expression node) { if (IsTerminal(node)) { return(node); } switch (node.NodeType) { case ExpressionType.Constant: return(base.Visit(node)); default: Value = GetValue(Evaluate(node)); return(node); } }
private static ConstantExpression GetVectorValue(FilterValue value, Type type) { var converter = TypeDescriptor.GetConverter(type); if (converter == null) { throw new InvalidOperationException($"Couldn't find type converter for type '{type.Name}'."); } var values = value.Value.Split(','); var vector = Array.CreateInstance(type, values.Length); for (var index = 0; index < values.Length; index++) { vector.SetValue(converter.ConvertFromString(values[index]), index); } return(Expression.Constant(vector)); }
public static Filter Parse(string text) { var or = Or.Match(text); if (or.Success) { return(new LogicalFilter ( Parse(or.Groups["Left"].Value), LogicalOperator.Or, Parse(or.Groups["Right"].Value) )); } var and = And.Match(text); if (and.Success) { return(new LogicalFilter ( Parse(and.Groups["Left"].Value), LogicalOperator.And, Parse(and.Groups["Right"].Value) )); } var predicate = Predicate.Match(text); if (predicate.Success) { return(new PredicateFilter ( FilterProperty.Parse(predicate.Groups["Property"].Value), PredicateOperator.Parse(predicate.Groups["Predicate"].Value), FilterValue.Parse(predicate.Groups["Value"].Value) )); } throw new ArgumentException($"Couldn't parse filter '{text}'."); }
public void Equal(FilterProperty left, FilterValue value) => _filter.Append($"{left}{PredicateOperatorString.Equal}{value}");
public void Any(FilterProperty property, FilterValue value) => _filter.Append($"{property}{PredicateOperatorString.Contains}{value}");
protected override Expression VisitConstant(ConstantExpression node) { Value = GetValue(node.Value); return(node); }
public FilterExpressionBuilder <T> NotEqual(FilterProperty property, FilterValue value) => Predicate(Expression.NotEqual, property, value, () => Expression.Constant(true));
public FilterExpressionBuilder <T> LessThanOrEqual(FilterProperty property, FilterValue value) => Predicate(Expression.LessThanOrEqual, property, value);
public PredicateFilter(FilterProperty property, PredicateOperator predicate, FilterValue value) { Property = property; Predicate = predicate; Value = value; }
public FilterExpressionBuilder <T> Any(FilterProperty property, FilterValue value) => Contains(FilterInfo.Any, property, value);
private FilterExpressionBuilder <T> Predicate(Func <Expression, Expression, Expression> factory, Expression property, FilterValue value, Func <Expression> fallback) { // TODO add stronger exception handling and conditional support for fallback Expression expression; try { expression = factory(property, GetScalarValue(value, property.Type)); } catch (FormatException e) { expression = fallback?.Invoke() ?? throw e; } _expressions.Push(expression); return(this); }
private FilterExpressionBuilder <T> Predicate(Func <Expression, Expression, Expression> factory, FilterProperty property, FilterValue value, Func <Expression> fallback = null) => Predicate(factory, GetProperty(property), value, fallback);
private FilterExpressionBuilder <T> Contains(MethodInfo method, FilterProperty property, FilterValue value) { var member = GetProperty(property); var collection = member.Type.Name == typeof(ICollection <>).Name ? member.Type : member.Type.GetTypeInfo().GetInterface(typeof(ICollection <>).Name); if (collection == null) { throw new InvalidOperationException($"Property '{property}' does not implement '{typeof(ICollection<>)}'."); } var type = collection.GetTypeInfo().GetGenericArguments().Single(); var item = Expression.Parameter(type); var contains = Expression.Lambda(Expression.Call(null, FilterInfo.Contains.MakeGenericMethod(type), member, item), item); var call = Expression.Call(null, method.MakeGenericMethod(type), GetVectorValue(value, type), contains); _expressions.Push(call); return(this); }
public void LessThan(FilterProperty property, FilterValue value) => _filter.Append($"{property}{PredicateOperatorString.LessThan}{value}");
public void NotEqual(FilterProperty property, FilterValue value) => _filter.Append($"{property}{PredicateOperatorString.NotEqual}{value}");
public FilterExpressionBuilder <T> GreaterThan(FilterProperty property, FilterValue value) => Predicate(Expression.GreaterThan, property, value);