Querying an object with LINQ using the Dyanmic field name

I created a dynamic search screen in ASP.NET MVC. I got the field names from the object through reflection so that I can allow the user to select the fields that they would like to search, instead of displaying all the fields in the view.

When the search result is returned to the controller, I get a FormCollection containing the NameName and Value field. I do not know how many fields are viewed, and FormCollection contains only those fields that have been selected by the user.

I want to be able to now take this field name and apply it to my LINQ statement when I query the database, for example:

public List<People> SearchPeople(Dictionary<string, string> fieldValueDictionary) { List<People> searchResults = new List<People>(); foreach (string key in fieldValueDictionary.Keys) { searchResults.Add(entities.People.Where(p => p.<use the key string as the fieldName> == fieldValueDictionary[key])); } return searchResults; } 

Where I use the key string as fieldName, it will look like p => p.FirstName == fieldValueDictionary [key] where key = "FirstName". I tried and did not use Lambda Expression Trees, and had little success in Dynamic LINQ. The only alternative is to do something like:

 public List<People> SearchPeople(Dictionary<string, string> fieldValueDictionary) { IQueryable<People> results = entities.People; foreach (string key in fieldValueDictionary.Keys) { switch (k) { case "FirstName": results = results.Where(entities.People.Where(p => p.FirstName == k); case "LastName": results = results.Where(entities.People.Where(p => p.LastName == k); // Repeat for all 26 fields in table } } return results.ToList<People>(); } 

UPDATE . I have done research in Lambda expression trees through the following posts:

dynamically create expressions lambdas + linq + OrderByDescending

Problem with Expression.Lambda () parameter

LINQ: passing a lambda expression as a parameter to be executed and returned by a method

I got to getting lambda to output the following: "p => p.FirstName", but I can't get this to work somewhere. Any suggestions? My code is below:

 MemberInfo member = typeof(People).GetProperty("FirstName"); ParameterExpression cParam = Expression.Parameter(typeof(People), "p"); Expression body = Expression.MakeMemberAccess(cParam, member); var lambda = Expression.Lambda(body, cParam); 
+2
source share
3 answers

After much more trial and error and searching, I accidentally found another SO post that addresses the same issue:

InvalidOperationException: no method 'Where' on type 'System.Linq.Queryable' is compatible with the arguments provided

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 fairly easy changes, I would have to get this to work with any type.

Thanks again for your answers Ani and John Bowen

+7
source

Have you tried to get the value from PropertyInfo?

 entities.People.Where(p => (p.GetType().GetProperty(key).GetValue(p, null) as string) == fieldValueDictionary[key]) 
+5
source
  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; ; } 
+1
source

Source: https://habr.com/ru/post/1497843/


All Articles