如何将用户输入字符串作为字段名传递,以访问对象中的字段
本文关键字:字段 访问 对象 输入 用户 字符串 | 更新日期: 2023-09-27 18:10:31
我正在使用linq从数据库中进行一些搜索。我有多个列名,如国家,姓名,电话号码…
现在我已经创建了一个下拉列表,并将用户选择的数据作为参数"searchedField"传递给我的控制器方法。现在,如果我输入一个"国家",我希望代码是
entries = entries.Where(s => s.country.Contains(searchString));
如果用户选择了"name"
entries = entries.Where(s => s.name.Contains(searchString));
请原谅我这个相当不合理的例子,因为我总是可以只是复制行和case,但我想知道是否有一种方法来利用像反射这样的东西来将字符串转换为"代码"来访问一个字段?
String searchedField = "name"
...
entries = entries.Where(s => s.searchedField.Contains(searchString));
这是我的第一个问题,谢谢!
你可以使用Dynamic Linq
entries = entries
.Where(
string.Format(
"{0} = '{1}'",
searchedField,
searchString
)
);
注意:根据字段的类型,你需要添加引号,或不。
你可以做一个反射查找(注意:我已经省略了错误检查):
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));
您可以为此构建一个表达式树(它将与Linq to实体一起工作)。
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);
一般来说,除了使用动态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"));