public SpecificationBase <T> Create <T>(FilterOption filter) { var expression = this.CreateExpression <T>(filter); if (expression == null) { return(null); } var spec = new SpecificationBase <T>(expression); return(spec); }
private Expression <Func <T, bool> > CreateMemberExpressionSimple <T>(FilterOption filter) { var left = ExpressionExtensions.MakePropertyExpression <T>(filter.Member); //TODO: change type var right = this.GetExpressionValue(filter, left.Item3); //FilterOperator Switch var assign = this.GetAssignExpression(left.Item3, filter.Operator, left.Item1, right); if (assign == null) { return(null); } return(Expression.Lambda <Func <T, bool> >(assign, left.Item2)); }
private Expression <Func <T, bool> > CreateExpression <T>(FilterOption filter) { //TODO: use c# 7 named value tuples or create an object with more explicit names Expression <Func <T, bool> > expression; var index = filter.Member.IndexOfAny(this.CompositeCharOperators); if (index > -1) { expression = this.CreateMemberExpressionComposite <T>(filter, index); } else { expression = this.CreateMemberExpressionSimple <T>(filter); } return(expression); }
private ConstantExpression GetExpressionValue(FilterOption filter, Type properType) { // Filter by month and year if (properType == typeof(DateTime) && (int.TryParse(filter.Value, out int c) || Regex.Match(filter.Value.ToString(), GenericConstants._GENERIC_MONTH_YEAR_EXPRESSION, RegexOptions.IgnoreCase).Success) || Regex.Match(filter.Value.ToString(), GenericConstants._GENERIC_YEAR_MONTH_EXPRESSION, RegexOptions.IgnoreCase).Success) { return(Expression.Constant(filter.Value.ConvertTo(typeof(string)), typeof(string))); } switch (filter.Operator) { case FilterOperator.IsLessThan: case FilterOperator.IsLessThanOrEqualTo: case FilterOperator.IsEqualTo: case FilterOperator.IsNotEqualTo: case FilterOperator.IsGreaterThan: case FilterOperator.IsGreaterThanOrEqualTo: case FilterOperator.StartsWith: case FilterOperator.EndsWith: case FilterOperator.Contains: case FilterOperator.DoesNotContain: var effectiveValue = filter.Value.ConvertTo(properType); return(Expression.Constant(effectiveValue, properType)); case FilterOperator.IsContainedIn: case FilterOperator.IsNotContainedIn: var array = filter.Value.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries); var arrayValues = array.Select(x => x.ConvertTo(properType)); var castMethod = EnumerableExtensions.CastMethod; var genericCastMethod = castMethod.MakeGenericMethod(properType); var obj = genericCastMethod.Invoke(null, new object[] { arrayValues }); return(Expression.Constant(obj)); default: throw new ArgumentOutOfRangeException(); } }
private Expression <Func <T, bool> > CreateMemberExpressionComposite <T>(FilterOption filter, int index) { var collectionPath = filter.Member.Substring(0, index); var separator = filter.Member[index]; var childPropertyPath = filter.Member.Substring(index + 1, (filter.Member.Length - (index + 1))); var childFilter = new FilterOption { Member = childPropertyPath, Operator = filter.Operator, Value = filter.Value }; var collectionInfo = ExpressionExtensions.MakePropertyExpression <T>(collectionPath); var collectionPropertyTye = collectionInfo.Item3; var collectionChildPropertyType = collectionPropertyTye.GenericTypeArguments[0]; var createMethod = CreateExpressionMethodInfo.MakeGenericMethod(collectionChildPropertyType); var childExpression = createMethod.Invoke(this, new object[] { childFilter }) as Expression; if (childExpression == null) { return(null); } var method = this.CompositeCharMethods[separator]; var concreteMethod = method.MakeGenericMethod(collectionChildPropertyType); IEnumerable <Expression> parameters = new[] { collectionInfo.Item1, childExpression }; var exp = Expression.Call(null, concreteMethod, parameters); var expression = Expression.Lambda <Func <T, bool> >(exp, collectionInfo.Item2); return(expression); }