Entity Framework 4.2 - Как реализовать наследование TPT с помощью значения Primarykey, созданного базой данных? - PullRequest
1 голос
/ 15 декабря 2011

Я хочу использовать EF (4.2) в следующем сценарии:

  • База данных уже существует (поэтому я выбрал подход, основанный на базе данных), и это база данных SQL Anywhere.
  • Я хочу использовать невежественные бизнес-объекты, поэтому я использую шаблон DbContext для генерации POCO классов из EDM.
  • Существует одна простая иерархия наследования среди моих сущностей:абстрактная базовая сущность и две конкретные производные сущности.
  • В базе данных имеется одна таблица для каждого типа иерархии наследования (Table-Per-Type Strategy).
  • Каждая из этих трех таблиц имеетстолбец первичного ключа (Id, тип: integer), и привязка конкретного объекта к базовому объекту выполняется с помощью одинакового Id в обеих таблицах (это означает, что первичный ключ (Id)) таблиц конкретных типов одновременно является внешним ключом к базовой таблице; я думаю, что это довольно распространенный подход).

Мне пришлось определить Inheritance вручную в конструкторе, sincПомощник по EDM не распознает автоматически, то есть хочет иметь связь наследования между описанными объектами.

До этого момента не было более серьезных проблем.Теперь к проблеме: есть ограничение для базы данных, которую я использую: Primarykey значения должны генерироваться базой данных, используя функцию базы данных.Я хочу вызвать эту функцию в before-insert-trigger, определенном в base-table.

. Чтобы структура сущностей знала, что значение генерируется базой данных, я устанавливаю свойство StoreGeneratedPattern * 1029.* Свойство от base-entity до Identity (как я понял, это способ сказать EF получать сгенерированное значение после вставки нового экземпляра сущности).

Когда я создаю новый экземплярпроизводного объекта, добавьте его к соответствующему DbSet из DbContext и вызовите SaveChanges в контексте, выдается DbUpdateException, заявляя, что ограничение foreignkey нарушено.Проверяя журнал запросов к базе данных, я вижу, что базовая сущность была вставлена ​​в базовую таблицу, но при вставке строки в производную таблицу возникает вышеупомянутая ошибка, поскольку она, очевидно, не использует вновь сгенерированный Id новой записи в базовой таблице.

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

Я знаю, что есть несколько способов избежать этой ситуации (не используя наследование, используя сохраненныйпроцедура для вставки новой производной сущности, вызывающая db-функцию, генерирующую id, перед вставкой и установки свойства Id для самой сущности), но на данный момент описанное выше поведение будет наиболее предпочтительным, поэтому я хочуубедитесь, что не пропустили что-то, прежде чем принять решение о каком-либо "плане B".приветствуется.

Вот код триггера:

ALTER TRIGGER "TRG_GENERATE_ID" before insert order 1 on
BASE_TABLE
referencing new as NewEntry
for each row
begin
  declare NewID integer;
  set NewID = F_GET_NEW_ID('BASE_TABLE', NewEntry.SOME_OTHER_ID);
  set NewEntry.ID = NewID
end

Функция "F_GET_NEW_ID" вызывается в триггере для генерации нового идентификатора для новой записибазовый стол.Он имеет два параметра: «Имя таблицы» -> Имя таблицы, для которой должен быть создан новый идентификатор, и второй параметр, который принимает значение стандартного столбца во всех таблицах базы данных (требуется для создания нового идентификатора.).

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