简体   繁体   中英

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

I use Entity Framework 6 and don't use 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

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 .

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:

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:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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