public static IEnumerable <T> FilterByRulesRecursivly <T>(IEnumerable <T> dataCollection, List <LinqFilterRule> rules) { if (!rules.Any()) { return(dataCollection); } // apply first rule LinqFilterRule rule = rules.First(); IEnumerable <T> filteredDataCollection = FilterByRule <T>(dataCollection, rule); return(FilterByRulesRecursivly(filteredDataCollection, rules.Skip(1).ToList())); }
private static Expression <Func <T, bool> > LambdaWhere <T>(LinqFilterRule filterRule) { string fieldName = filterRule.Property; object fieldValue = filterRule.Value; string comparer = filterRule.Comparison; var parameter = Expression.Parameter(typeof(T), "t"); var property = Expression.Property(parameter, fieldName); var value = Expression.Constant(fieldValue); var converted = Expression.Convert(value, property.Type); Expression <Func <T, bool> > lambda = null; switch (comparer) { case Const.COMPARISON_NOT_EQUAL: lambda = Expression.Lambda <Func <T, bool> >(Expression.NotEqual(property, converted), parameter); break; case Const.COMPARISON_GREATER: lambda = Expression.Lambda <Func <T, bool> >(Expression.GreaterThan(property, converted), parameter); break; case Const.COMPARISON_GREATER_OR_EQUAL: lambda = Expression.Lambda <Func <T, bool> >(Expression.GreaterThanOrEqual(property, converted), parameter); break; case Const.COMPARISON_LESS: lambda = Expression.Lambda <Func <T, bool> >(Expression.LessThan(property, converted), parameter); break; case Const.COMPARISON_LESS_OR_EQUAL: lambda = Expression.Lambda <Func <T, bool> >(Expression.LessThanOrEqual(property, converted), parameter); break; case Const.COMPARISON_IS_NULL: lambda = Expression.Lambda <Func <T, bool> >(Expression.Equal(property, null), parameter); break; case Const.COMPARISON_IS_NOT_NULL: lambda = Expression.Lambda <Func <T, bool> >(Expression.NotEqual(property, null), parameter); break; case Const.COMPARISON_IN: lambda = Expression.Lambda <Func <T, bool> >(Expression.Call(property, ContainsMethodInfo, converted), parameter); break; case Const.COMPARISON_NOT_IN: MethodInfo methodContains = typeof(string).GetMethod("Contains", new[] { typeof(string) }); var contains = Expression.Call(property, ContainsMethodInfo, converted); var notContains = Expression.Not(contains); lambda = Expression.Lambda <Func <T, bool> >(notContains, parameter); break; default: try { lambda = Expression.Lambda <Func <T, bool> >(Expression.Equal(property, converted), parameter); } catch (Exception ex) { string mess = ex.Message; throw ex; } break; } return(lambda); }
static IEnumerable <T> FilterByRule <T>(IEnumerable <T> dataCollection, LinqFilterRule rule) { var lambdaWhere = LambdaWhere <T>(rule); return(dataCollection.Where(lambdaWhere.Compile())); }