/// <summary> /// Method that generate filter string ends with comparison expression /// </summary> /// <param name="memberExp">Member expression</param> /// <param name="filterProperty">KeyValuePair for properties and values</param> /// <param name="property">Property that will be filtered</param> /// <returns>Expression for the filter string ends with comparison</returns> internal static Expression GenerateStringEndsWithExpression( Expression memberExp, ConstantExpression tokenExp ) { return(Expression.Call(memberExp, ReflectionsHelper.GetMethodFromType(memberExp.Type, "EndsWith", 1, 0, new List <Type> { typeof(string) }), tokenExp)); }
/// <summary> /// Method that generate filter string contains comparison expression /// </summary> /// <param name="memberExp">Member expression</param> /// <param name="filterProperty">KeyValuePair for properties and values</param> /// <param name="property">Property that will be filtered</param> /// <returns>Expression for the filter string contains comparison</returns> internal static Expression GenerateStringContainsExpression( Expression memberExp, ConstantExpression tokenExp ) { var method = ReflectionsHelper.GetMethodFromType(memberExp.Type, "Contains", 1, 0, new List <Type> { typeof(string) }); return(Expression.Call(memberExp, method, tokenExp)); }
/// <summary> /// Method that generates a lambda expression for search criteria /// </summary> /// <typeparam name="TSource">Expression type attribute</typeparam> /// <param name="searchableProperties">List of searchable properties</param> /// <param name="terms">List of terms to search</param> /// <param name="queryStrict">parameter that indicates when all terms should be contained in the property</param> /// <returns>Lambda expression for the search</returns> internal static Expression <Func <TSource, bool> > GenerateSearchCriteriaExpression <TSource>( IList <string> searchableProperties, IList <string> terms, bool queryStrict) where TSource : class { List <Expression> orExpressions = new List <Expression>(); var xExp = Expression.Parameter(typeof(TSource), "x"); foreach (var propertyInfo in typeof(TSource).GetProperties().Where(x => searchableProperties.Any(y => y.ToLower().Equals(x.Name.ToLower())) && !CriteriasHelper.GetNonQueryableTypes().Any(type => type == x.PropertyType) ).ToList()) { Expression memberExp = Expression.MakeMemberAccess(xExp, propertyInfo); Expression memberHasValue = null; if (memberExp.Type != typeof(string)) { if (Nullable.GetUnderlyingType(memberExp.Type) != null) { memberHasValue = Expression.MakeMemberAccess(memberExp, memberExp.Type.GetProperty("HasValue")); memberHasValue = queryStrict ? memberHasValue : Expression.Not(memberHasValue); } else if (memberExp.Type.IsClass) { memberHasValue = Expression.Equal(memberExp, Expression.Constant(null)); memberHasValue = !queryStrict ? memberHasValue : Expression.Not(memberHasValue); } memberExp = Expression.Call(memberExp, ReflectionsHelper.GetMethodFromType(memberExp.Type, "ToString", 0, 0)); } else { memberHasValue = Expression.Equal(memberExp, Expression.Constant(null)); memberHasValue = !queryStrict ? memberHasValue : Expression.Not(memberHasValue); } memberExp = Expression.Call(memberExp, ReflectionsHelper.GetMethodFromType(memberExp.Type, "ToLower", 0, 0)); List <Expression> andExpressions = new List <Expression>(); foreach (var token in terms) { andExpressions.Add(ExpressionsHelper.GenerateStringContainsExpression(memberExp, Expression.Constant(token, typeof(string)))); } orExpressions.Add(queryStrict ? ExpressionsHelper.GenerateAndExpressions(andExpressions) : ExpressionsHelper.GenerateOrExpression(andExpressions)); } Expression orExp = ExpressionsHelper.GenerateOrExpression(orExpressions); return(Expression.Lambda <Func <TSource, bool> >(orExp.Reduce(), xExp)); }