Заполните свойства навигации при использовании в методе, переданном предложению Where - PullRequest
0 голосов
/ 07 марта 2019

У меня есть конечная точка, которая должна перечислять все кандидатуры, отфильтрованные по поисковому запросу, поэтому я создаю метод, который принимает сущность кандидата и searchTerm в качестве параметров. Затем я передаю этот метод предложению Where, но проблема в том, что я получил NullReferenceException, потому что свойства навигации равны нулю. Если я помещаю оператор внутри предложения Where вместо метода, тогда он не throw Exception. Вопрос в том, как это исправить, но я хочу сохранить внешний метод, потому что там будет намного больше логики, но мне нужно иметь доступ ко всем navigation properties, т.е. они должны быть заполнены.

if (!string.IsNullOrEmpty(searchTerm))
{
    query = query.Where(c => FilterBySearchTerm(c, searchTerm));
}

var result = await query.Select(c => new CandidaturesResponseModel()
{
    Id = c.Id,
    Name = c.PrimaryMember.FullName, // that's filled
}).ToListAsync();

private bool FilterBySearchTerm(Candidature c, string searchTerm)
{
    return c.PrimaryMember.FirstName.Contains(searchTerm); // here is the exception because PrimaryMember navigation property is null. So I want this to be filled.
}

Ответы [ 2 ]

1 голос
/ 07 марта 2019

Проблема в том, что вы материализуете запрос, используя метод FilterBySearchTerm.EF не может преобразовать случайные методы в SQL, поэтому он должен пойти дальше и выполнить запрос, получить результаты обратно, а затем применить Where.EF на самом деле генерировал исключение в прошлом, но EF Core обрабатывает это молча.

В любом случае, как только запрос будет выполнен, все готово.Ваша фильтрация происходит в памяти, и в этот момент без Include ваши связанные сущности не будут там работать.Короче говоря, вам нужно построить свой фильтр на месте (а не использовать отдельный метод), чтобы EF смог перевести его на SQL.

Альтернативный подход, который может вам лучше помочь, этопередать запрос к вашему FilterBySearchTerm методу.Например, вместо того, чтобы делать:

query = query.Where(c => FilterBySearchTerm(c, searchTerm));

Do

query = FilterBySearchTerm(query, searchTerm);

Затем внутри FilterBySearchTerm вы можете напрямую применять предложения Where к переданному запросу.Это позволяет вам создавать фактический запрос, который EF может понять, и в то же время инкапсулировать логику.

1 голос
/ 07 марта 2019

Просто используйте Include метод, чтобы добавить PrimaryMember

  query = query.Include(x=> x.PrimaryMember).Where(c => FilterBySearchTerm(c, searchTerm));
...