1

Here is my code. Can anyone help me refactor this piece of code. i'm trying to use field name as variable so I wouldn't have to use switch case. Something like from dr in db.Users where dr.FieldName.Contains(value).

public static List<User> GetUser(string value, string fieldName)
{
    var db = new CCPTDataContext();
    var users = new List<User>();

    switch (fieldName)
    {
        case "FirstName":
            users = (from dr in db.Users where dr.FirstName.Contains(value)
                     select new User
                     {
                         Username = dr.Username,
                         FirstName = dr.FirstName,
                         LastName = dr.LastName
                     }).ToList();

            break;
        case "LastName":
            users = (from dr in db.Users where dr.LastName.Contains(value)
                     select new User
                     {
                         Username = dr.Username,
                         FirstName = dr.FirstName,
                         LastName = dr.LastName
                     }).ToList();
            break;
    }
    return users;
}
1

2 Answers 2

4

You have to create the Expression Tree manually using classes from System.Linq.Expression namespace:

public static Expression<Func<TSource, bool>> GetPropertyContainsValueExpression<TSource>(string propertyName, string value)
{
    var param = Expression.Parameter(typeof(TSource), "x");
    var prop = Expression.Property(param, propertyName);
    var valueExp = Expression.Constant(value, typeof(string));
    var contains = Expression.Call(prop, "Contains", null, valueExp);
    return Expression.Lambda<Func<TSource, bool>>(contains, param);
}

then you can use it like that:

public static List<User> GetUser(string value, string fieldName)
{
    var db = new CCPTDataContext();

    return db.Users.Where(GetPropertyContainsValueExpression<User>(fieldName, value)).ToList();
}
Sign up to request clarification or add additional context in comments.

4 Comments

Some providers (I think EF 5) might not correctly parameterize the query in the above snippet. In order to get the parameterized queries, what I do is wrap the value in a Tuple and get the Item1 property: var container = new Tuple<string>(value); var containerExpression = Expression.Constant(container, typeof(Tuple<string>)); var valueExp = Expression.Property(containerExpression, "Item1");
@Kosar you're welcome! You should consider marking the answer as accepted if it solved your problem. That's how SO works!
@Marcin, I tried to mark as accepted, couldn't find any link, button or something like that for it. Can you guide me how to do that.
@Kosar Right below post score the should be gray mark you can click. Here is a great question about that: meta.stackexchange.com/questions/5234/…
0

This should work:

users = (from dr in db.Users 
where (fieldName.Equals("FirstName") && dr.FirstName.Contains(value))
      || (fieldName.Equals("LastName") && dr.LastName.Contains(value))
                 select new User
                 {
                     Username = dr.Username,
                     FirstName = dr.FirstName,
                     LastName = dr.LastName
                 }).ToList();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.