I have created a dynamic search screen in ASP.NET MVC. I retrieved the field names from the entity through reflection so that I could allow the user to choose which fields
After a lot more trial and error and searching I accidentally found another SO post that covers the same issue:
InvalidOperationException: No method 'Where' on type 'System.Linq.Queryable' is compatible with the supplied arguments
Here is my modified code that works:
IQueryable query = entities.People;
Type[] exprArgTypes = { query.ElementType };
string propToWhere = "FirstName";
ParameterExpression p = Expression.Parameter(typeof(People), "p");
MemberExpression member = Expression.PropertyOrField(p, propToWhere);
LambdaExpression lambda = Expression.Lambda<Func<People, bool>>(Expression.Equal(member, Expression.Constant("Scott")), p);
MethodCallExpression methodCall = Expression.Call(typeof(Queryable), "Where", exprArgTypes, query.Expression, lambda);
IQueryable q = query.Provider.CreateQuery(methodCall);
With some hopefully pretty easy modifications, I should be able to get this to work with any type.
Thanks again for your answers Ani & John Bowen
public List<People> SearchPeople(Dictionary<string, string> fieldValueDictionary)
{
return !fieldValueDictionary.Any()
? entities.People
: entities.People.Where(p => fieldValueDictionary.All(kvp => PropertyStringEquals(p, kvp.Key, kvp.Value)))
.ToList();
}
private bool PropertyStringEquals(object obj, string propertyName, string comparison)
{
var val = obj.GetType().GetProperty(propertyName).GetValue(obj, null);
return val == null ? comparison == null : val.ToString() == comparison; ;
}
Have you tried getting the value from PropertyInfo?
entities.People.Where(p => (p.GetType().GetProperty(key).GetValue(p, null) as string) == fieldValueDictionary[key])