5

I'm doing a little bit of search from a database using linq. I have multiple column names like country, name, phone number...

Now I've created a dropdownlist and pass the user selected data as a parameter "searchedField" to my controller method. Now if I take the input of a "country", I expect the code to be

    entries = entries.Where(s => s.country.Contains(searchString));

If user selected "name"

    entries = entries.Where(s => s.name.Contains(searchString));

Excuse me for this rather unreasonable example, since I can always just copy lines and make cases, but I wonder if there is a way to utilize things like reflection to convert string to "code" to access a field?

    String searchedField = "name"

    ...

    entries = entries.Where(s => s.searchedField.Contains(searchString));

This is my first question here, thanks!

3

4 Answers 4

3

You can use Dynamic Linq.

entries = entries
    .Where(
        string.Format(
            "{0} = '{1}'",
            searchedField,
            searchString
        )
    );

Note: depending on the type of field you'll need to add quotes, or not.

Sign up to request clarification or add additional context in comments.

Comments

1

You can do a reflection lookup (note: I've omitted error checking):

string GetPropertyAsString(object obj, string propertyName)
{
  var propertyInfo - obj.GetType().GetProperty(propertyName);
  return propertyInfo.GetValue(obj).ToString();
}

and then say

entries = entries.Where(s => GetPropertyAsString(s, searchedField).Contains(searchString));

Comments

1

You can build an expression tree for this (which will work with Linq to entities).

public static class QueryableExtensions {
   public static IQueryable<T> Filter<T>(this IQueryable<T> queryable, string propertyName, string searchValue)
        {
            var type = typeof (T);
           //this will be the left part of the lambda
            var parameter = Expression.Parameter(type, "s");
            //s.country for example
            var property = Expression.Property(parameter, propertyName);
            //string.Contains method
            var containsMethod = typeof (string).GetMethod("Contains", new[] {typeof (string)});
            //s.country.Contains(<yoursearchvalue>)
            var expression = Expression.Call(property, containsMethod, Expression.Constant(searchValue));
            //s => s.country.Contains(<yoursearchvalue>)
            var lambda = Expression.Lambda<Func<T, bool>>(expression, parameter);
            //filter your queryable with predicate
            return queryable.Where(lambda);
        }
}

usage

var fieldtosearch = "country";
entries = entries.Filter(fieldtosearch , searchString);

Comments

0

In general, other than using dynamic linq queries, you could also use Expression to build a generic method to construct a property Getter and use it in your linq query, a quick sampel:

    public static Func<TObject, TProperty> GetPropGetter<TObject, TProperty>(string propertyName)
    {
        ParameterExpression paramExpression = Expression.Parameter(typeof(TObject), "value");
        Expression propertyGetterExpression = Expression.Property(paramExpression, propertyName);
        Func<TObject, TProperty> result =
            Expression.Lambda<Func<TObject, TProperty>>(propertyGetterExpression, paramExpression).Compile();
        return result;
    }

to use it:

        var getter = GetPropGetter<YourEntity, string>("Name");
        var found = entites.Where(m => getter(m).Contains("someInput")); 

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.