Reputation: 1066
I was wondering if any of you has an idea on how to tackle this problem.
Suppose there's the following class
public class Person
{
public string Description {get; set;}
//...
}
I'd like to create an expression that can be passed in to LINQ's Where
method in LINQ's Where
method in LINQ to SQL, such as the following:
Expression<Func<Person, bool>> expression = x => x.Description.Contains("foo");
The real problem here is that I don't know what field is going to be checked until runtime. The name of the property is provided as a string (in this case it would be "Description", but it can be "Description2", or any other property of the Person
class). I can't use reflection directly in the expression itself to get the property value (by using GetType
, GetProperty
etc.) because the expression won't work when passed to Where
in LINQ to SQL because it can't be translated to an SQL code. Thanks in advance!
Upvotes: 0
Views: 80
Reputation: 4218
Have a look at this minimal example, the desired property will be accessed and compared with another string, resulting in a boolean:
// GET: People
public ActionResult Index()
{
var propertyName = "Description";
var compareString = "abc";
var parameter = Expression.Parameter(typeof(Person));
var memberAccess = Expression.MakeMemberAccess(parameter, typeof(Person).GetProperty(propertyName));
var compare = Expression.Constant(compareString);
var contains = Expression.Call(memberAccess, typeof(string).GetMethod(nameof(string.Contains), new[] { typeof(string) }), compare);
var expr = Expression.Lambda<Func<Person, bool>>(contains, new[] { parameter });
return View(db.People.Where(expr).ToList());
}
Of course this is missing all checks, possible options, cache, ... The point is, you have to create the expression by yourself if you have to rely on runtime known types.
Upvotes: 2