TheBoubou
TheBoubou

Reputation: 19933

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
        };

}

Upvotes: 9

Views: 7978

Answers (3)

TDaver
TDaver

Reputation: 7264

As a matter of fact it is possible using the Expression API:

public void Searching(Expression<Func<User,string>> field, string stringToSearch)
{

   var call = Expression.Call(field.Body, typeof (string).GetMethod("Contains"), new[] {Expression.Constant(value)});
   Expression<Func<User, bool>> exp = Expression.Lambda<Func<User, bool>>(Expression.Equal(call, Expression.Constant(true)), field.Parameters);


    var res =  _dataContext.USERs.Where(exp).Select(u=>new { id= u.ID, Username = u.USERNAME});

}

Upvotes: 4

Marc Gravell
Marc Gravell

Reputation: 1064104

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();

Upvotes: 15

jeroenh
jeroenh

Reputation: 26792

What you are trying is not possible. You can however use the dynamic linq library to achieve what you want

Upvotes: 3

Related Questions