Проблема с отложенной загрузкой в ​​рамках сущности - PullRequest
2 голосов
/ 30 апреля 2011

У меня есть две сущности в отношении 1: n: ссылка, категория. Сначала я получаю все категории и ссылки и помещаю их в список. Затем я заполняю ссылки каждой категории вручную, но category.Links.Add(link) подключается к БД и снова получает ссылку, и это приводит к двойным данным в результате. Я знаю, что это действие из-за ленивой загрузки. ленивая загрузка - это правда, и я не хочу ее отключать. Как я могу заполнить ссылки каждой категории вручную, не подключаясь к БД снова? Пожалуйста, не предлагайте загружать Eager или отключать ленивый груз.

        var categories = categoryRepository.GetCategories().ToList();
        var allLinks = linkRepository.GetLinks().ToList();

        foreach (var category in categories)
        {
            var links = allLinks.Where(l => l.CategoryID == category.CategoryID);

            foreach (var link in links)
            {
                category.Links.Add(link);
            }
        }

1 Ответ

1 голос
/ 01 мая 2011

Даже если вы упомянули, что не хотите отключать отложенную загрузку, я настаиваю на этом, потому что отложенная загрузка всегда будет запускаться при первом обращении к свойству навигации.Единственный способ избежать этого:

  • Отключение отложенной загрузки.Недостатком является то, что вы должны отключить ленивую загрузку для всей обработки категорий.Потому что, как только вы включите его, он сразу же перезагрузит Links при следующем доступе к свойству.Причина в том, что EntityCollection, используемый для обработки Links, имеет свойство IsLoaded, которое является ложным (и не может быть изменено, кроме как путем вызова Load).
  • Удаление ключевого слова virtual из коллекции Links,Это запретит перенос только Category динамическим прокси и из-за этого не допустит отложенной загрузки.Это будет еще интереснее, потому что единственным необходимым кодом в вашей загрузке должны быть первые две строки - ссылки будут автоматически заполняться категориями во время выполнения второго запроса.Проблема здесь в том, что удаление виртуального ключевого слова из автоматически сгенерированных сущностей является сложным (оно должно быть жестко запрограммировано в шаблон T4), или вы должны использовать собственную сущность.
  • Каким-то образом обманывать EF, заменяя EntityCollection в Links свойствес другой коллекцией.Это не легко, потому что вы не можете просто назначить новую коллекцию для Links - динамический прокси выдаст InvalidOperationException.Вы должны создать вторую частичную часть вашей сущности и добавить некоторый код, который будет напрямую изменять приватное поле, содержащее коллекцию (в обход свойства).Даже такой подход может иметь некоторые плохие последствия.Код по умолчанию использует некоторые исправления и т. Д.

Отключение отложенной загрузки не нарушит вашу функциональность - на самом деле EF делает это довольно часто внутри страны.Вам просто нужно сделать:

context.ContextOptions.LazyLoadingEnabled = false;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...