Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use string as field name in LINQ

Look the code below. I'd like to replace USERNAME by the field name received in the parameter field. This method must be able to make some search on several fields.

Thank,

public void Searching(string field, string stringToSearch)
{
    var res = 
        from user in _dataContext.USERs where 
        user.USERNAME.Contains(stringToSearch)
        select new 
        {
          Id = user.ID,
          Username = user.USERNAME
        };

}
like image 229
Kris-I Avatar asked Jun 26 '12 09:06

Kris-I


1 Answers

You need to forget about the anonymous type, maybe use Tuple<int,string> instead; but: how about:

IQueryable<Foo> source = // YOUR SOURCE HERE
      // in-memory dummy example:
      // source = new[] {
      //    new Foo {Id = 1, Bar = "abc"},
      //    new Foo {Id = 2, Bar = "def"}
      // }.AsQueryable();

string field = "Bar";
string stringToSearch = "d";
var param = Expression.Parameter(typeof (Foo), "x");
var predicate = Expression.Lambda<Func<Foo, bool>>(
    Expression.Call(
        Expression.PropertyOrField(param, field),
        "Contains", null, Expression.Constant(stringToSearch)
    ), param);
var projection = Expression.Lambda<Func<Foo, Tuple<int, string>>>(
    Expression.Call(typeof(Tuple), "Create", new[] {typeof(int), typeof(string)},
        Expression.PropertyOrField(param, "Id"),
        Expression.PropertyOrField(param, field)), param);
Tuple<int,string>[] data = source.Where(predicate).Select(projection).ToArray();
like image 175
Marc Gravell Avatar answered Sep 26 '22 22:09

Marc Gravell