如何将用户输入字符串作为字段名称传递以访问对象中的字段?

时间:2014-06-26 09:16:01

标签: c# linq system.reflection

我正在使用linq从数据库中进行一些搜索。我有多个列名,如国家/地区,姓名,电话号码......

现在我已经创建了一个下拉列表,并将用户选择的数据作为参数传递给#34; searchingField"到我的控制器方法。现在如果我接受" country"的输入,我希望代码是

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

如果用户选择"名称"

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

请原谅我这个相当不合理的例子,因为我总是可以复制线条并制作案例,但我想知道是否有办法利用像反射这样的东西将字符串转换为"代码"访问一个字段?

    String searchedField = "name"

    ...

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

这是我的第一个问题,谢谢!

4 个答案:

答案 0 :(得分:3)

您可以使用Dynamic Linq

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

注意:根据您需要添加引号的字段类型。

答案 1 :(得分:1)

你可以进行反射查找(注意:我省略了错误检查):

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

然后说

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

答案 2 :(得分:1)

您可以为此构建表达式树(适用于Linq到实体)。

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

使用

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

答案 3 :(得分:0)

通常,除了使用动态linq查询之外,您还可以使用Expression构建一个通用方法来构造属性Getter并在您的linq查询中使用它,这是一个快速的样本:

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

使用它:

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