繁体   English   中英

表达<Func<object, bool> &gt; 作为财产

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM