EF Navigation Property Looping Issue - PullRequest
1 голос
/ 15 июня 2011

У меня в настоящее время есть БД, которая выглядит примерно так

Person Table
Id
Name
AddressLookupTypeId


AddressLookupType Table
Id
Description
SortOrder

Когда я использую конструктор Entity Framework 4.0 и добавляю две таблицы, я получаю свойство навигации для обоих классов, то есть:

Person Class
Id
Name
AddressLookupType - Nav Property


AddressStatusLookup Class
Id
Description
SortOrder
Person - Navigation Property

Теперь моя личная таблица содержит около 3 с лишним миллионов записей, а тип адреса содержит только около 50 записей.Когда я обновляю статус на любом человеке и вызываю изменения сохранения по какой-то причине, для обновления требуется вечность;если я делаю паузу и отлаживаюсь в середине выполнения кода, я получаю метод FixupAddressStatusLookup.Я не знаю, что именно здесь происходит, но мне кажется, что он проходит через подмножество записей Person, имеющих одинаковый тип адреса;Это только мое лучшее предположение, хотя.Если я удаляю свойство навигации Person из класса AddressStatusLookup в конструкторе, то код выполняется немедленно.Кто-нибудь может объяснить, что здесь происходит?Почему наличие свойства навигации Person для моего AddressStatusLookup вызывает такие задержки?

Спасибо

Ответы [ 3 ]

2 голосов
/ 15 июня 2011

Ваш метод исправления выглядит примерно так:

private void FixupAddressStatusLookup(AddressStatusLookup previousValue)
{
    if (previousValue != null && previousValue.Persons.Contains(this))
    {
        previousValue.Persons.Remove(this);
    }

    // more ...
}

Он вызывается в установщике свойства навигации AddressStatusLookup в вашем классе Person.

Теперь представьте, что у вас включена отложенная загрузка , и вы присваиваете новую AddressStatusLookup сущности Person (вызывается установщик и, следовательно, метод исправления): previousValue.Persons.Something... вызывает отложенную загрузку для выполнить запрос к базе данных, которая загружает всех людей, у которых значение AddressStatusLookup равно previousValue - то есть с вашими миллионами людей и всего 50 стати, вероятно, список из тысяч или сотен тысяч записей о людях, которые были загружены до Contains оправдан вообще.

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

Для решения проблемы вы можете попробовать:

  • Удалите коллекцию Person из своего класса AddressStatusLookup (как вы уже пытались с успехом). Его полезность в любом случае сомнительна.
  • Или: не работать с отложенной загрузкой
  • Или: Удалить методы fixup из сгенерированных классов. (Возможно, можно настроить шаблоны T4 и создать собственный шаблон для подавления генерации этих методов, но я не уверен.)

(Если у вас не включена отложенная загрузка, этот ответ, вероятно, совершенно бесполезен.)

1 голос
/ 15 июня 2011

Похоже, вы используете шаблоны T4 POCO?Если это так, то вы видите, что работает код FixUp, который фиксирует отношения от одного конца к другому.Я нахожу, что он не работает для нетривиальных баз данных, так как он проходит через множество концов отношений, чтобы гарантировать, что обратные указатели все установлены правильно.Лучшее, что вы можете сделать, это отключить LazyLoading в контексте. ContoxtOptions и загрузить отношения, когда они вам нужны, с помощью Include и т. Д.

РЕДАКТИРОВАТЬ: чуть больше объяснения того, что происходит, можно найти здесь http://blogs.msdn.com/b/efdesign/archive/2010/03/10/poco-template-code-generation-options.aspx

Кроме того, сгенерированные объекты ADO.NET SelfTrackingEntity Generator не загружаются лениво, поэтому не делайте этого.

0 голосов
/ 06 октября 2014

Для этой конкретной операции установите Context.ContextOptions.LazyLoadingEnabled = false;после завершения сохранения сбросьте его на true.

...