Динамический фильтр для предложения where в Entity Framework 6 (без LINQKit) - PullRequest
0 голосов
/ 18 марта 2019

Я использую Entity Framework 6 и не использую LINQKit.

Допустим, у нас есть пользовательский интерфейс, в котором пользователь может фильтровать клиентов только по имени ИЛИ только по фамилии ИЛИ по имени и фамилии (это чрезвычайно упрощено, но отражает мою ситуацию).

Если я использую статический фильтр - он работает:

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

Но если я попытаюсь создать тот же фильтр динамически:

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

- происходит сбой за исключением:

Параметр 'u' не был связан в указанном запросе LINQ to Entities выражение

Но мне нужно создать фильтр динамически, потому что это зависит от пользователя, какое условие фильтра он выберет.

Так как правильно построить динамический фильтр?

1 Ответ

0 голосов
/ 18 марта 2019

Параметр (c) в обоих выражениях не совпадает, см. Ответ на этот вопрос SO .

Вы можете получить выражения для использования одного и того же параметра типа, используябиблиотека выражений.

Сначала создайте параметр типа:

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

... затем создайте равные выражения с помощью объявленного параметра типа:

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

и:

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

Затем вы можете использовать параметр типа для создания фильтра и выполнения запроса:

var expr = Expression.And(nameExpression, surnameExpression);
var dynamicFilter = Expression.Lambda<Func<Client, bool>>(expr, typeParameter);
var filteredClientsDynamicFilter = context.Clients.Where(dynamicFilter).ToList();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...