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; } } ```

Original source