public static IQueryable<T> SearchBy<T>(this IQueryable<T> query, Dictionary<string, StringValues> searchTerms, LambdaLogicalOp logicalOp) { if (searchTerms.Any()) { var predicate = PredicateBuilder.New<T>(true); foreach (var searchTerm in searchTerms) { ParameterExpression param = Expression.Parameter(typeof(T), "x"); MemberExpression memberExpression = Expression.MakeMemberAccess(param, typeof(T).GetProperty(searchTerm.Key)); // TODO: this assumes properties are of type string. This will need to be refactored to account for numeric and date types MethodInfo methodInfo = typeof(string).GetMethod("Contains", new Type[] {typeof(string)}); var toLowerExpression = Expression.Call(memberExpression, ToLowerMethod); var tempSearchTerm = searchTerm.Value.ToString(); ConstantExpression constant = Expression.Constant(tempSearchTerm.ToLower()); var call = Expression.Call(toLowerExpression, methodInfo, constant); Expression<Func<T, bool>> lambda = Expression.Lambda<Func<T, bool>>(call, param); if (logicalOp == LambdaLogicalOp.And) { predicate = predicate.And(lambda); } else { predicate = predicate.Or(lambda); } } query = query.AsExpandable().Where(predicate); return query; } return query; }
public static IQueryable<T> SearchBy<T>(this IQueryable<T> query, string searchTerm, string[] attributes, LambdaLogicalOp logicalOp) { if (attributes.Any()) { var predicate = PredicateBuilder.New<T>(true); foreach (var attibute in attributes) { if (!string.IsNullOrEmpty(attibute)) { ParameterExpression param = Expression.Parameter(typeof(T), "x"); MemberExpression memberExpression = Expression.MakeMemberAccess(param, typeof(T).GetProperty(attibute)); // TODO: this assumes properties are of type string. This will need to be refactored to // account for numeric and date types MethodInfo methodInfo = typeof(string).GetMethod("Contains", new Type[] { typeof(string) }); var toLowerExpression = Expression.Call(memberExpression, ToLowerMethod); var tempSearchTerm = searchTerm; // used to avoid the outer variable trap ConstantExpression constant = Expression.Constant(tempSearchTerm); var call = Expression.Call(toLowerExpression, methodInfo, constant); //var call = Expression.Call(toLowerCall, methodInfo, toLowerCall); Expression<Func<T, bool>> lambda = Expression.Lambda<Func<T, bool>>(call, param); if (logicalOp == LambdaLogicalOp.And) { predicate = predicate.And(lambda); } else { predicate = predicate.Or(lambda); } //query = query.AsExpandable().Where(lambda); } } query = query.AsExpandable().Where(predicate);//.AsQueryable(); return query; } return query; }