Linq search by different values

I have a class like this:

class Person
{
    private String sName;
    private String sPhone;
    private String sAge;
    private String sE_Mail;
    // … code …
}

And I have to search by the value received from the user, it can be any attribute of this class. I also have:

public IEnumerable<Person> SearchByPhone(string value)
{
    return from person in personCollection                   
           where person.**SPhone** == value
           select person;
}

I have four methods like this, the only difference is the attribute. Please can someone tell me how can I do this with only one method or not possible? Thank.

+5
source share
3 answers

No need to write separate methods. One method is enough:

public IEnumerable<Person> Search<T>(T value, Func<Person,T> mapFunc)
{
    return from person in personCollection                   
           where mapFunc(person).Equals(value)
           select person;
 }

Then name it like this:

Search("SOME VALUE", input=>input.sPhone);  //sPhone must be public
Search("SOME VALUE", input=>input.sAge);     //sAge must be public
+5
source

You can use linq dynamic library to do this

public IQueryable<Person> Search(string column, string value)
{
    return personCollection.Where(string.Format("{0} = @1", column), value);
}

Or you can create expressions yourself:

public IQueryable<Person> Search(string column, string value)
{
    var param = Expression.Parameter(typeof(T), "x");
    var prop = Expression.Property(param, column);
    var val = Expression.Constant(value, prop.Type);
    var equals = Expression.Equal(prop, val);
    var lambda = Expression.Lambda(equals, param);
    return personCollection.Where(lambda);
}
+3
source

The easiest way is to make a where statement in the or operation.

public IEnumerable<Person> SearchByValue(string value)
{
    return from person in personCollection
           where (person.sName.Equals(value) || 
               person.sPhone.Equals(value) || person.sAge.Equals(value) || 
               person.sE_Mail.Equals(value));
}

I personally prefer to use a fluent api as it is less verbose and makes the LINQ command chain together more obvious ... here this implementation is also

public IEnumerable<Person> SearchByValue(string value)
{
    return personCollection.Where(p => p.sName.Equals(value) || 
               p.sPhone.Equals(value) || p.sAge.Equals(value) || 
               p.sE_Mail.Equals(value));
}
+1
source

All Articles