简体   繁体   English

动态过滤Entity Framework 6中的where子句(不带LINQKit)

[英]Dynamic filter for where clause in Entity Framework 6 (without LINQKit)

I use Entity Framework 6 and don't use LINQKit. 我使用实体框架6,而不使用LINQKit。

Let's say we have UI where user can filter clients only by Name OR only by Surname OR by Name and Surname (it's extremely simplified but depicts my situation). 假设我们有一个用户界面,用户只能按名称或按姓氏或按名称和姓氏过滤客户端(这非常简化,但描述了我的情况)。

If I use static filter - it's working: 如果我使用静态过滤器-它可以正常工作:

Expression<Func<Client, Boolean>> staticFilter = (c) => c.Name.Equals(someName) && c.Surname.Equals(someSurname);
var filteredClientsStaticFilter = context.Clients.Where(staticFilter).ToList(); 

But if I try to create the same filter dynamically: 但是,如果我尝试动态创建相同的过滤器:

Expression<Func<Client, Boolean>> nameFilter = (c) => c.Name.Equals(someName);
Expression<Func<Client, Boolean>> surnameFilter = (c) => c.Surname.Equals(someSurname);

var expr = Expression.And(nameFilter.Body, surnameFilter.Body);
var dynamicFilter = Expression.Lambda<Func<Client, Boolean>>(expr, nameFilter.Parameters[0]);
var filteredClientsDynamicFilter = context.Clients.Where(dynamicFilter).ToList();

- it fails with exception: -失败,但出现以下异常:

The parameter 'u' was not bound in the specified LINQ to Entities query expression 在指定的LINQ to Entities查询表达式中未绑定参数“ u”

But I need to create filter dynamically because it depends on user which filter condition he choose. 但是我需要动态创建过滤器,因为它取决于用户选择的过滤条件。

So how can I build dynamic filter correctly? 那么如何正确构建动态过滤器?

The (c) parameter of your both expressions are not the same, see the answer to this SO question . 两个表达式的(c)参数不相同,请参见此SO问题的答案。

You can get the expressions to use the same type parameter by using the Expression library. 通过使用表达式库,可以使表达式使用相同的类型参数。

First, create the type parameter: 首先,创建类型参数:

var typeParameter = Expression.Parameter(typeof(Client), "c");

...then create the equal expressions by using the declared type parameter: ...然后使用声明的type参数创建相等表达式:

var nameProperty = Expression.Property(typeParameter, nameof(Client.Name));
var nameExpression = Expression.Equal(nameProperty, Expression.Constant(someName));

and: 和:

var surnameProperty = Expression.Property(typeParameter, nameof(Client.Surname));
var surnameExpression = Expression.Equal(surnameProperty, Expression.Constant(someSurname));

You can then use the type parameter to create your filter and execute your query: 然后,您可以使用type参数来创建过滤器并执行查询:

var expr = Expression.And(nameExpression, surnameExpression);
var dynamicFilter = Expression.Lambda<Func<Client, bool>>(expr, typeParameter);
var filteredClientsDynamicFilter = context.Clients.Where(dynamicFilter).ToList();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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