I\'m basically trying to construct a query, and I don\'t know why microsoft made this so difficult in Entity Framework and LINQ. I have various parameter STRINGS. So if you
This is not trivial, but I believe it can be done. The following has not been tested. The code is borrowed from here.
Create a helper method somewhere like
public static Expression> GetContainsExpression(string propertyName, string containsValue)
{
var parameterExp = Expression.Parameter(typeof(T), "type");
var propertyExp = Expression.Property(parameterExp, propertyName);
MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
var someValue = Expression.Constant(propertyValue, typeof(string));
var containsMethodExp = Expression.Call(propertyExp, method, someValue);
return Expression.Lambda>(containsMethodExp, parameterExp);
}
public static Expression> GetPropertyExpression(string propertyName)
{
var parameterExp = Expression.Parameter(typeof(T), "type");
var exp = Expression.Property(parameterExp, propertyName);
return Expression.Lambda>(exp, parameterExp);
}
Use it like
users = this.entities.tableUsers
.Where(GetContainsExpression(searchfield, search))
.OrderBy(GetPropertyExpression(searchfield))
...
UPDATE
As an alternative, you could create extension methods to provide a cleaner syntax. Create the following methods in a static class somewhere:
public static IQueryable WhereStringContains(this IQueryable query, string propertyName, string contains)
{
var parameter = Expression.Parameter(typeof(T), "type");
var propertyExpression = Expression.Property(parameter, propertyName);
MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
var someValue = Expression.Constant(contains, typeof(string));
var containsExpression = Expression.Call(propertyExpression, method, someValue);
return query.Where(Expression.Lambda>(containsExpression, parameter));
}
public static IOrderedQueryable OrderBy(this IQueryable query, string propertyName)
{
var propertyType = typeof(T).GetProperty(propertyName).PropertyType;
var parameter = Expression.Parameter(typeof(T), "type");
var propertyExpression = Expression.Property(parameter, propertyName);
var lambda = Expression.Lambda(propertyExpression, new[] { parameter });
return typeof(Queryable).GetMethods()
.Where(m => m.Name == "OrderBy" && m.GetParameters().Length == 2)
.Single()
.MakeGenericMethod(new[] { typeof(T), propertyType })
.Invoke(null, new object[] { query, lambda }) as IOrderedQueryable;
}
public static IOrderedQueryable OrderByDescending(this IQueryable query, string propertyName)
{
var propertyType = typeof(T).GetProperty(propertyName).PropertyType;
var parameter = Expression.Parameter(typeof(T), "type");
var propertyExpression = Expression.Property(parameter, propertyName);
var lambda = Expression.Lambda(propertyExpression, new[] { parameter });
return typeof(Queryable).GetMethods()
.Where(m => m.Name == "OrderByDescending" && m.GetParameters().Length == 2)
.Single()
.MakeGenericMethod(new[] { typeof(T), propertyType })
.Invoke(null, new object[] { query, lambda }) as IOrderedQueryable;
}
Then you can call them like:
var users = this.entities.tableUsers.WhereStringContains(searchField, search)
.OrderBy(searchField);