我有一个查询,我需要对其应用n个过滤器。但是我必须使用表达式。到目前为止,我已经为每个过滤器构建了表达式,这非常好。问题是我想将这些过滤器连接到一个表达式中,因此我可以将它用作LINQ的.Where()的参数。
过滤代码:
//Filters could slightly differ in functionality
private Expression<Func<T, bool>> StringPropertyContains<T>(Filter filter)
{
if (filter == null)
{
throw new ArgumentNullException(nameof(filter));
}
if (typeof(T).GetProperties().FirstOrDefault(pi => pi.Name.Equals(filter.PropertyName, StringComparison.OrdinalIgnoreCase)) == null)
{
throw new ArgumentNullException($"Type {typeof(T)} does not contain property {filter.PropertyName}");
}
var propertyInfo = typeof(T).GetProperty(filter.PropertyName);
var param = Expression.Parameter(typeof(T));
var member = Expression.MakeMemberAccess(param, propertyInfo);
var constant = Expression.Constant(filter.Value, typeof(filter.Type));
var methodInfo = typeof(filter.Type).GetMethod(filter.Method, new Type[] { typeof(filter.Type) });
var body = Expression.Call(member, methodInfo, constant);
return Expression.Lambda<Func<T, bool>>(body, param);
}
private Expression<Func<T, bool>> Filter<T>(T t)
{
//TODO join filters while each filter should have its different parameter
//the parameter is currently constructed in the object and is accessible via property Filter[] ParsedFilter
}
过滤类:
internal class Filter
{
public string Type { get; }
public string Method { get; }
public string PropertyName { get; }
public string Value { get; }
}
所需用法:
IQueryable<T> q = query.Where(this.Filter)
老实说,我对这个问题非常头疼,因为我对表达方式很陌生。所以感谢您的帮助。
答案 0 :(得分:0)
您不能将类作为参数传递给Where子句,但是您可以使用Linq表达式来实现您想要的内容:
Expression<Func<T, bool>> filter = q => q.type == filter.Type && q.Value == filter.Value;
var x = query.Where(filter);