Linq to Entities с пользовательским методом в Where

У меня есть сложный запрос LINQ to Entities, который становится слишком длинным. Я хочу разделить его на несколько хорошо названных методов, чтобы другие могли его понять. Этот пост, кажется, подразумевает, что я могу сделать это, пока я возвращаю Expression EF, который может перевести. https://stackoverflow.com/a/18338476/4812782

Вот мой упрощенный код. Я не могу получить данные перед фильтрацией, потому что это будет более 100 000 записей. Моя база данных Oracle.

var q = _context.vehicles
    .Where(x => IsActiveVehicle())
    .ToList()

Expression<Func<tb_vehicle, bool>> IsActiveVehicle()
            {
                return vehicle => vehicle.type == "R" &&
                       vehicle.status != "E" &&
                       vehicle.deleted == false;
            }

я получаю ошибку

Невозможно неявно преобразовать тип «System.Linq.Expressions.Expression>» в «bool». Невозможно преобразовать лямбда-выражение в предполагаемый тип делегата, поскольку некоторые возвращаемые типы в блоке не могут быть неявно преобразованы в возвращаемый тип делегата.

Любая помощь приветствуется.


person Ashley    schedule 25.10.2019    source источник
comment
Похоже, вы хотите Where(IsActiveVehicle())   -  person juharr    schedule 25.10.2019


Ответы (1)


Это неверно, как указано в ошибке:

.Where(x => IsActiveVehicle())

Это создает новое выражение, содержащее ваше выражение.

Вы действительно хотите передать Expression<Func<>> в .Where.

var q = _context.vehicles
    .Where(IsActiveVehicle())
    .ToList()

Обратите внимание на вопрос/ответ, который вы связали, и вы его увидите.


Другой способ взглянуть на это:

.Where(x => IsActiveVehicle())

Означает следующую ерунду:

.Where(x => ((vehicle) => vehicle.type == "R" &&
                       vehicle.status != "E" &&
                       vehicle.deleted == false))

Однако это:

.Where(IsActiveVehicle())

Означает следующее, что имеет больше смысла:

.Where(vehicle => vehicle.type == "R" &&
                       vehicle.status != "E" &&
                       vehicle.deleted == false)
person IOrlandoni    schedule 25.10.2019
comment
Я полностью пропустил это! Спасибо!! У меня, вероятно, будет около 10 пользовательских методов, подобных этому. Можно ли как-то связать их вместе в одном предложении where или мне понадобится новое предложение where для каждого? - person Ashley; 25.10.2019
comment
Например, .Where(IsActiveVehicle && IsNotDocked()) - person Ashley; 25.10.2019
comment
Предполагая, что вы планируете связать их с AND, лучший способ — сделать несколько вызовов .Where(). - person IOrlandoni; 25.10.2019