Использование StoreGeneratedPattern.Identity со значениями первичного ключа, созданного триггером базы данных, невозможно? - PullRequest
3 голосов
/ 27 декабря 2011

Этот вопрос связан с другим вопросом, который я задал здесь ( Entity Framework 4.2 - Как реализовать наследование TPT с помощью значения первичного ключа, генерируемого базой данных? ) и должен просто уточнить, если мои предположения, касаются проблемы заявлено в теме, правы или нет.

Проблема (подробно):

  • Я хочу использовать EF (4.1) для доступа к базе данных, которая уже существует
  • база данных имеет некоторые ограничения относительно генерации значений первичного ключа для своих таблиц (есть UDF, который берет имя таблицы и возвращает следующий доступный идентификатор)
  • Чтобы упростить для себя задачу, мой первый подход состоял в том, чтобы определить триггеры базы данных (перед вставкой), которые вызывают UDF, генерирующий ID, для установки нового идентификатора при вставке нового datarow
  • Затем я установил свойства StoreGeneratedPattern соответствующих сущностей в csdl моего EDM на «Identity», чтобы вновь созданные идентификаторы были установлены в объектах сущностей после сохранения их в DB

Результат этого был:

Когда я создал новый объект-сущность, добавил его в DbContext и вызвал для него SaveChanges, соответствующий элемент данных был вставлен в базу данных, но объект не был обновлен с использованием нового идентификатора, созданного в базе данных. Я понял это, когда попытался сохранить больше сразу, которые имеют ассоциации друг с другом (parent-child), потому что свойства внешнего ключа дочерних объектов не могли быть установлены правильно, так как новый идентификатор родителя не был известен DbContext.

Вот почему я задал вышеупомянутый вопрос о наследовании TPT.

После нескольких дней исследований и попыток всего, что мне пришло в голову, решить эту проблему, я думаю, я понял, что это просто не может работать. Хотя документация перечисления StoreGeneratedPattern на MSDN и несколько пояснений в блогах предполагает, что StoreGeneratedPattern.Identity должен быть установлен для получения сгенерированного значения, когда БД генерирует значение при вставке новой строки, это не верно для первичных ключей в сочетании с триггерами базы данных.

После долгих размышлений об этом мне кажется вполне логичным, поскольку EF нужен какой-то критерий для извлечения значений, сгенерированных базой данных, и я думаю, что в большинстве случаев это будет идентичность сущности. Для столбцов базы данных, для которых задано автоинкремент (или идентификатор-столбца, ...), это может быть проблемой, поскольку СУБД предоставляет некоторые функции для извлечения последнего вставленного значения-идентификатора (например, @@ identity в MSSQL). Но при использовании триггера для генерации нового значения идентификатора EF, очевидно, не знает, как запросить вновь вставленную строку (и я не могу представить какой-либо хороший независимый от БД способ сделать это либо).

Итак, мой актуальный вопрос: верны ли предположения выше, или я упускаю здесь что-то важное?

Заранее спасибо за любые разъяснения / вдохновение по этому вопросу.

Редактировать (следующий вопрос):

После прочтения ответа от Ладислава возникает другой вопрос:

Если я устанавливаю StoreGeneratedPattern в CSDL, нужно ли мне устанавливать для него такое же значение в SSDL (и наоборот)? Патч для дизайнера edm подразумевает, что это так, потому что он автоматически синхронизирует StoreGeneratedPattern в SSDL при изменении его в CSDL (через конструктор).

Ответы [ 2 ]

1 голос
/ 27 декабря 2011

StoreGeneratedPattern.Identity должно работать.Если вы установили его в EF Designer, убедитесь, что он был правильно настроен как в SSDL, так и в CSDL-части файла EDMX (откройте его как XML, чтобы проверить это).В конструкторе EF была ошибка, которая приводила к корректной настройке только в CSDL, поэтому часть SQL не знала, что новый идентификатор должен быть выбран из базы данных после вставки.В некоторых редких случаях эта ошибка была устранена установкой VS 2010 SP1 , и ее обязательно нужно устранить специальным патчем .

0 голосов
/ 05 июля 2012

У меня была такая же проблема: один столбец был установлен с триггером.

Но оказалось, что у меня были проблемы с конструктором VS edmx («Идентификация» не была установлена), и это помоглоисправить это вручную (одна модель имела правильное значение, а другая - нет).

Затем мы получили «Оператор сохранения, вставки или удаления магазина затронул неожиданное количество строк (0). Возможно, объекты были измененыили удалены, так как объекты были загружены. Обновить записи ObjectStateManager ".Это легко исправить, следуя инструкциям здесь

Если я устанавливаю StoreGeneratedPattern в CSDL, нужно ли мне устанавливать такое же значение в SSDL (и наоборот)?

Да, похоже, не работает без изменений как CSDL, так и SSDL

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