我试图在具有大量列的表/视图上实现对列的文本搜索,并且由于这些列会不时发生变化,因此我想使用反射来动态创建查询在C#中。
我想要的是这样的
SELECT * FROM VW_PRILOZENA_DOK WHERE LOWER(VW_PRILOZENA_DOK.*propName*)
LIKE LOWER('*searchText*')
Lambda表达式,例如:
table.Where(s => s.*propName*.ToLower().Contains(*searchText*)
将是我所需要的,但是因为我需要反思,所以它行不通。
因此,我需要使用显式表达式。这就是我所拥有的:
private static readonly MethodInfo Contains = typeof(string).GetMethod("Contains", new[] { typeof(string)});
public static Expression<Func<VW_PRILOZENA_DOK, bool>> SearchPredicate(IEnumerable<string> properties, string searchText)
{
if (String.IsNullOrWhiteSpace(searchText) == false)
{
var param = Expression.Parameter(typeof(VW_PRILOZENA_DOK));
var search = Expression.Constant(searchText);
var components = properties
.Select(propName => Expression.Call(Expression.Property(param, propName), Contains, search))
.Cast<Expression>()
.ToList();
var body = components
.Skip(1)
.Aggregate(components[0], Expression.OrElse);
return Expression.Lambda<Func<VW_PRILOZENA_DOK, bool>>(body, param);
}
return m => true;
}
灵感来自:How to write string.Contains(someText) in expression Tree
我要将此函数的结果传递给的地方。()
的地方这是可行的,但是我缺少下套管。 我对linq不太了解,但是有人可以帮我解决这个问题吗?
编辑:反射部分是使用反射生成的属性列表。
解决了它!
.Select(propName =>
{
var dynamicExpression = Expression.Call(Expression.Property(param, propName), ToLower);
return Expression.Call(dynamicExpression, Contains, search);
})
现在,就linq而言,谁能告诉我这是否是我的查询的一个好解决方案?