[英]How to convert Linq Expression<Func<object,object,bool>> to Expression<Func<T1,T2,bool>>
[英]Expression<Func<object, bool>> as Property
我正在尝试为通用存储库重构一些代码,该代码传入将过滤数据以及页面、排序等的过滤器对象。
每个继承Filter
(例如 CustomerFilter)都可以选择定义自己的表达式过滤器,该过滤器将由存储库中的基类应用。
因此,客户过滤器将具有如下属性:
public string CustomerId { get; set; }
public override Expression<Func<object, bool>> Predicate => c => ((Customer)c).Id == CustomerId;
然后存储库将在存储库中运行过滤器,有点像这样(它还不是通用的!):
using (var context = new CustomerContext())
{
return await Filter<Domain.Customer>.ApplyAsync(filter, context.Customers.AsQueryable()).ConfigureAwait(false);
}
这工作正常,但我需要一种方法来为更复杂的示例以更好的方式构建表达式。
例如,过滤器可能允许过滤状态上的客户,但前提是它已设置。
public string CustomerId { get; set; }
public State? CustomerState { get; set; }
public override Expression<Func<object, bool>> Predicate => c => (((Customer)c).Id == CustomerId) && (((Customer)c).State == CustomerState ?? (Customer)c).State);
这不仅变得一团糟,而且还有很多不必要的强制转换和括号。 所以我想做的是 getter 中的表达式构建器,它将以更简洁的方式构建表达式,例如if(State != null) { CustomerState == State; }
if(State != null) { CustomerState == State; }
. 但那是我不确定如何继续的地方,所以如果有人能帮助我,我会很感激。
如果您想组合多个“条件”以应用于 Where 子句,您可以使用LinqKit库中的 PredicateBuilder
这是将两个条件与“Or”子句组合的示例
System.Linq.Expressions.Expression<Func<Domain.Question, bool>> codition1 = e => e.CategoryId == 1;
System.Linq.Expressions.Expression<Func<Domain.Question, bool>> condition2 = e => e.CategoryId == 2;
var combinedCondition = LinqKit.PredicateBuilder.Or(codition1, condition2);
//using combined condition in where clause....
queryable = queryable.Where(combinedCondition);
您可以使用PredicateBuilder类的其他方法(例如“And”)来获取您想要的组合条件...
您可以将表达式与Linq Expressions API结合使用:
public Expression<Func<Customer, bool>> BuildExpression()
{
Expression<Func<Customer, bool>> predicate = c => c.Id == CustomerId;
if (State != null)
{
var parameter = predicate.Parameters.First();
var newBody = Expression.AndAlso(
predicate.Body,
Expression.Equal(
Expression.PropertyOrField(parameter, nameof(State)),
Expression.Constant(State)
));
predicate = Expression.Lambda<Func<Customer, bool>>(newBody, parameter);
}
return predicate;
}
在上面的代码中, predicate
是一个基表达式,如果State
为null,将使用该表达式。 但是当设置State
时,我们提取表达式参数并将&& c.State == State
添加到谓词体
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.