Entity Framework Core - отложенная загрузка не работает для получателей - PullRequest
1 голос
/ 19 июня 2019

Давайте предположим, что этот сценарий

Entity

public virtual List<Address> AddressHistory { get; set; }

public Address Address
{
    get
    {
        if (AddressHistory.Any())
        {
            return AddressHistory.OrderByDescending(x => x.CreationDate).FirstOrDefault();
        }

        return null;
    }
}

При запросе адреса на основе условия, например:

dbContext.MyEntity.Where(e => e.Address.Street == "some stuff");

Я получаю исключение нулевой ссылки.

Почему? Есть ли способ заставить его работать?

РЕДАКТИРОВАТЬ: для тех, кто думает, что Адрес может быть пустым, он работает при этом:

dbContext.MyEntity.Where(e => e.AddressHistory.OrderByDescending(x => x.CreationDate).FirstOrDefault().Street == "some stuff");

РЕДАКТИРОВАТЬ: Парню, который пометил его как дубликат, я не думаю, что вы понимаете проблему здесь. Пожалуйста, удалите маркировку.

Итак, подведем итог:

Если я использую исключение getter => null, потому что потомки (AdressHistory) загружаются не лениво. Если я использую код внутри геттеров непосредственно в выражении efcore, он работает.

Это означает, что использование геттера не работает в EFCore.

1 Ответ

4 голосов
/ 19 июня 2019

Вы правы, это не работает. И я не думаю, что это когда-либо будет.

В EF Core в настоящее время возникают проблемы с оценкой клиента свойств навигации (загружены как ленивые, так и нетерпеливые). Это одна из причин, по которой оценка клиента будет удалена в следующей основной версии EF Core (3.0). И запросы, использующие такие выражения, будут просто генерировать исключения, подобные EF6.

Учитывая все это, не используйте такие вспомогательные свойства в запросах LINQ to Entities. Я знаю, что это хорошо с точки зрения ООП и возможности повторного использования, но трансляция запросов LINQ плохо сочетается с инкапсуляцией, поскольку она основана на знаниях и должна видеть код (выражение) за всем, что не является частью отображения модели в базу данных.

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

...