Объекты, сохраненные в неправильном порядке без открытых внешних ключей - PullRequest
3 голосов
/ 16 августа 2011

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

OrderHeader
 - OrderID (PK)

OrderDetails
 - OrderID (PK)
 - DetailID (PK)

(есть больше столбцов, но они не имеют значения).

Примечание: Мы не разоблачаемистинный внешний ключ для OrderDetails.OrderID, но вместо этого мы используем триггеры, чтобы обеспечить наличие идентификатора OrderID таблицы Details в таблице Header.Разоблачение FK может быть быстрым решением, но в нашем приложении такие изменения в базе данных не допускаются - нам приходится иметь дело с унаследованным кодом и т. Д.

Просмотр XML в .edmxФайл, который создает дизайнер, я заметил, что он создает AssociationSet и Association в Концептуальной модели (раздел CSDL) - и Association настроен с ReferentialConstraint.Однако, это не делает AssociateSet или Ассоциацию в разделе SSDL.Похоже, что они добавляются только тогда, когда FK выставляется в базе данных.Для других баз данных, которые я тестировал (например, AdventureWorks или Northwind), в которых есть истинные FK в базе данных, при создании модели из базы данных я вижу, что EDMX включает в себя разделы Association и AssociationSet в SSDL.

Похоже, что EF игнорирует ассоциацию, которую мы имеем в модели (CSDL), и вместо этого просто вставляет в алфавитном порядке по имени таблицы - так что в этом случае нам не повезло, так как OrderDetail сортирует перед OrderHeader (а у нас, конечно, нетвозможность переименовывать таблицы в нашем случае).Если я вручную добавлю соответствующий AssociationSet и Association в разделе SSDL, сохранение произойдет в правильном порядке (сначала вставьте заголовок, затем вставьте Detail).Тем не менее, каждый раз, когда мы делаем «Обновление модели из базы данных», эти ручные изменения исчезают, поэтому это не очень практичное решение.Я думал о том, чтобы попытаться выполнить это исправление динамически во время выполнения, но кажется, что это много усилий, чтобы обойти что-то, что должно «просто работать».

Я надеюсь, что есть способчто EF может уважать Ссылочное ограничение и / или Ассоциацию, которые определены в CSDL, когда он заказывает Вставки.

Ответы [ 3 ]

3 голосов
/ 16 августа 2011

Мне кажется, я понимаю проблему сейчас.У вас вообще нет отношений в SSDL.Когда EF генерирует команды SQL, он использует только информацию из SSDL, поэтому он не знает о зависимости между сущностями, определенными в CSDL.Я проверю это позже, но это похоже на ошибку / дизайн ошибки в архитектуре EF.

Что вы можете сделать, чтобы избежать ошибки?Определите наборы ассоциаций вручную в SSDL и используйте какой-нибудь лучший инструмент (коммерческий) для работы с EF-дизайнером и отображения обновлений - или перейдите к ручному ведению EDMX, потому что дизайнер предназначен только для простых сценариев.

Вы также можете сообщить о поведении как об ошибке на MS Connect или указать его в качестве заявки в службу поддержки, если вы сотрудничаете с Microsoft, но помните, что даже если вы получите решение, оно потребуетнесколько месяцев.

2 голосов
/ 19 августа 2011

Услышав ответ Ладислава Мрнкки и не в силах найти собственное решение, я нашел альтернативное решение.Это потребовало некоторых усилий, но, на мой взгляд, конечный результат того стоит.

Я сделал расширение Visual Studio, использующее метод IModelTransofmrationExtension.OnBeforeModelSaved () .В этом методе вы получаете документ EDMX как XDocument, и вы можете манипулировать им по своему усмотрению, прежде чем он будет сохранен.Я использую эту возможность для сканирования раздела CSDL на наличие ассоциаций и наборов ассоциаций, которых нет в SSDL.Затем я копирую их в раздел SSDL - после сопоставления имен сущностей / свойств с именами таблиц / столбцов с данными в секции MSL.

Это эффективно «обманывает» EF, заставляя думать, что для наших ассоциаций существуют реальные внешние ключи, поэтомуон делает вставки в правильном порядке.

Единственным недостатком является то, что все члены нашей команды, которые редактируют модели, должны иметь установленное расширение, иначе они не получат сгенерированные FK-ассоциации.К счастью, у нас есть несколько человек, которые редактируют модели, так что это легко.

1 голос
/ 16 августа 2011

За исключением перехода на фактическое использование FK, не уверен, что вы можете делать то, что вы хотите из коробки.Вы пытались просто поместить всю вставку (в правильном порядке и использовать предложение output, чтобы вернуть идентификатор, если они являются идентификаторами для второй вставки) в сохраненный процесс и заставить EF вызывать этот процесс?

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