表达式< Func<对象,布尔>作为财产 [英] Expression<Func<object, bool>> as Property

查看:47
本文介绍了表达式< Func<对象,布尔>作为财产的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为通用存储库重构一些代码,该代码传递了一个过滤对象,该对象将过滤数据以及页面,排序等.

每个继承 Filter (例如CustomerFilter)的选项都可以定义自己的表达式过滤器,该表达式过滤器将由存储库中的基类应用.

因此客户过滤器将具有以下属性:

 公共字符串CustomerId {get;放;}公共替代表达式< Func<对象,布尔>>谓词=>c =>((客户)c).Id ==客户ID; 

然后,存储库将在存储库中运行过滤器,有点像这样(它还不是通用的!):

 使用(var context = new CustomerContext()){返回等待Filter< Domain.Customer> .ApplyAsync(filter,context.Customers.AsQueryable()).ConfigureAwait(false);} 

这行得通,但是我需要一种方法来为更复杂的示例更好地构建表达式.

例如,过滤器可以允许根据状态对客户进行过滤,但前提是要设置状态.

 公共字符串CustomerId {get;放;}公共国家?CustomerState {get;放;}公共替代表达式< Func<对象,布尔>>谓词=>c =>((((Customer)c).Id == CustomerId)&&((((Customer)c).State == CustomerState ??(Customer)c).State); 

这不仅变得一团糟,而且还有很多不必要的强制转换和括号.因此,我想做的是在getter中创建一个表达式生成器,它将以一种更简洁的方式构建表达式,例如 if(State!= null){CustomerState == State;} .但这就是我不确定如何进行的地方,所以如果有人可以帮助我,我将不胜感激.

解决方案

如果要合并多个条件",应用于Where子句,您可以使用 LinqKit

中的PredicateBuilder这里是将两个条件与或"组合的示例.条款

  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);//在where子句中使用组合条件queryable = queryable.Where(combinedCondition); 

您可以使用 PredicateBuilder 类的其他方法,例如"And"和获得您想要的综合条件...

I am trying to refactor some code for a generic repository, that passes in a filter object that will filter data, as well as page, sort etc.

Each inheriting Filter (Such as CustomerFilter) has the option of defining its own Expression Filter which will get applied by the base class in the repository.

So the customer filter will have properties like this:

public string CustomerId { get; set; }

public override Expression<Func<object, bool>> Predicate => c => ((Customer)c).Id == CustomerId;

Then the repository will run the filter in the repository, a bit like this (it's not generic yet!):

using (var context = new CustomerContext())
{
      return await Filter<Domain.Customer>.ApplyAsync(filter, context.Customers.AsQueryable()).ConfigureAwait(false);
}

This works ok, but I need a way to build the expression in a better way for more complex examples.

For example, the filter may allow to filter the customers on the state, but only if its set.

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);

This not only becomes a mess, but also there's a lot of unnecessary casting and parenthesis. So what I'd like to do is an expression builder in the getter, that would build the expression in a cleaner way, such as if(State != null) { CustomerState == State; }. But that's where I'm not sure how to proceed, so if anyone can help me out, I'd appreciate it.

解决方案

If you want to combine multiple "Conditions" to apply to Where clause you can use PredicateBuilder from LinqKit library

Here is an example to combine two conditions with "Or" clause

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);

You can use other methods of PredicateBuilder class such as "And" to get the combined condition you want...

这篇关于表达式&lt; Func&lt;对象,布尔&gt;作为财产的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆