Entity Framework 4 и сохраняющиеся отношения внешнего ключа - PullRequest
0 голосов
/ 18 мая 2010

Я в значительной степени новичок в Entity Framework (в частности, в версии 4), и я пытаюсь понять возникшую у меня проблему.

У меня есть проект ASP.NET MVC2, который я использую с Entity Framework 4 и классом репозитория. У меня есть простое отношение внешнего ключа, которое я определил. Когда я запускаю свой проект MVC, я могу загрузить форму MVC и обновить отношение внешнего ключа, установив идентификатор внешнего ключа на моем объекте. Я делаю это, вызывая OnPropertyIDChanging в частичном классе и устанавливая EntityKey следующим образом:

this.ManufacturerReference.EntityKey = new System.Data.EntityKey("MachinesEntities.Manufacturers", "ManufacturerId", value);

Я создал второй проект, который представляет собой проект командной строки, который я использую для загрузки начальных данных для модели. Однако, когда я вызываю объект Repository, чтобы добавить сущность, я не могу вставить значения Null в таблицу дочерних сущностей (Manufacturer). Если я явно устанавливаю ссылку на родительский объект (Product) на дочерний объект (Manufacturer), вызывая мой репозиторий для получения объекта производителя и устанавливая объект производителя продукта, я получаю исключение, в котором указано

На объект сущности нельзя ссылаться несколькими случаями IEntityChangeTracker

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

Проводя некоторые исследования, я увидел, что при загрузке объекта из запроса, что объектные отношения явно создаются через объект RelationshipEntry. Этого не происходит при создании объектов в приложении командной строки. Какой способ обойти это? Я предполагаю, что у меня возникнет та же проблема, если я попытаюсь создать веб-службу, поскольку я создаю объект без предварительного вызова SQL.

Во-вторых, есть ли лучшая практика по управлению контекстом? Лучше ли иметь контекст, созданный и расположенный внутри каждого метода репозитория, глобальную ссылку в каждом из объектов репозитория или контекст, который передается каждому конструктору репозитория?

Спасибо!

John

1 Ответ

3 голосов
/ 18 мая 2010

Во-вторых, есть ли лучшая практика по управлению контекстом? Лучше ли создавать и размещать контекст в каждом методе репозитория, глобальную ссылку в каждом из объектов репозитория или контекст, который передается каждому конструктору репозитория?

На самом деле, это важная проблема. Исправьте это, а другой должен уйти.

Контекст должен быть единицей работы. Так что для вашего веб-приложения это будет один запрос. Должен быть ровно один контекст на единицу работы. Используйте DI, чтобы поделиться им со всем кодом, который участвует в этой единице работы, возможно, через ваши репозитории.

Для вашего приложения командной строки определите, какова единица работы.

Это сообщение:

На объект сущности нельзя ссылаться несколькими экземплярами IEntityChangeTracker

... просто означает: «Вы не можете связать две сущности, которые принадлежат к разным контекстам. Настоящая проблема здесь заключается в одновременном существовании двух разных контекстов одновременно. Это не невозможно, но так сложно получить право, я считаю это метод «только для экспертов».

Этот хак:

this.ManufacturerReference.EntityKey = new System.Data.EntityKey("MachinesEntities.Manufacturers", "ManufacturerId", value);

... больше не требуется в EF 4. В EF 4 вы можете сгенерировать вашу модель с ассоциациями FK, а затем просто выполните:

this.ManufacturerId = value;
...