Linq IQueryable Generic Filter
c#, c#-4.0, entity-framework, linq
Solution
void Main()
{
// creates a clause like
// select * from Menu where MenuText like '%ASD%' or ActionName like '%ASD%' or....
var items = Menu.Filter("ASD").ToList();
}
// Define other methods and classes here
public static class QueryExtensions
{
public static IQueryable<T> Filter<T>(this IQueryable<T> query, string search)
{
var properties = typeof(T).GetProperties().Where(p =>
/*p.GetCustomAttributes(typeof(System.Data.Objects.DataClasses.EdmScalarPropertyAttribute),true).Any() && */
p.PropertyType == typeof(String));
var predicate = PredicateBuilder.False<T>();
foreach (var property in properties )
{
predicate = predicate.Or(CreateLike<T>(property,search));
}
return query.AsExpandable().Where(predicate);
}
private static Expression<Func<T,bool>> CreateLike<T>( PropertyInfo prop, string value)
{
var parameter = Expression.Parameter(typeof(T), "f");
var propertyAccess = Expression.MakeMemberAccess(parameter, prop);
var like = Expression.Call(propertyAccess, "Contains", null, Expression.Constant(value,typeof(string)));
return Expression.Lambda<Func<T, bool>>(like, parameter);
}
}
You need to add reference to LinqKit to use PredicateBuilder and AsExpandable method otherwise won't work with EF, only with Linq to SQL
If you want `Col1 like '%ASD%' AND Col2 like '%ASD%' et`, change `PredicateBuilder.False` to `PredicateBuilder.True` and `predicate.Or` to `predicate.And`
Also you need to find a way to distinguish mapped properties by your own custom properties (defined in partial classes for example)
Problem
I am looking for a generic Filter for the searchText in the query of any Column/Field mapping ``` public static IQueryable<T> Filter<T>(this IQueryable<T> source, string searchTerm) { var propNames = typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(e=>e.PropertyType == typeof(String)).Select(x => x.Name).ToArray(); //I am getting the property names but How can I create Expression for source.Where(Expression) } ``` Here I am giving you an example scenario Now From my HTML5 Table in Asp.net MVC4 , I have provided a Search box to filter results of entered text , which can match any of the below columns/ Menu class Property values , and I want to do this search in Server side , how can I implement it. EF Model Class ``` public partial class Menu { public int Id { get; set; } public string MenuText { get; set; } public string ActionName { get; set; } public string ControllerName { get; set; } public string Icon { get; set; } public string ToolTip { get; set; } public int RoleId { get; set; } public virtual Role Role { get; set; } } ```