我正在使用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));
这是我的第一个问题,谢谢!
答案 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"));