Вставка «один ко многим» в Entity Framework — нарушение внешнего ключа

#c# #oracle #entity-framework

#c# #Oracle #entity-framework

Вопрос:

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

Мои примеры таблиц:

 table APPOINTMENTS: ID, VAR1, DATE_APPOINTMENT
table GUESTS: ID, APPOINTMENT_ID, USER_ID, VAR2, VAR3
  

Мой тестовый код:

 DomainService aux = new DomainService();

APPOINTMENTS appointment = new APPOINTMENTS();
appointment.VAR1 = "BLA";
appointment.DATE_APPOINTMENT = new DateTime();

//The user with id = 1 is already created in the database
appointment.GUESTS.Add(new GUESTS { USER_ID = 1, VAR2 = 1, VAR3 = "F" });

aux.InsertAppointment(appointment);
  

В DomainService у меня есть:

 public void InsertAppointment(APPOINTMENTS appointment)
{
    using (var context = this.ObjectContext)
    {
        context.AddToAPPOINTMENTS(appointment);
        context.SaveChanges();
    }
}
  

Но я получаю эту ошибку:
{«ORA-02291: нарушено ограничение целостности (FK_GUESTS_APPOINTMENTS) — родительский ключ не найден»}

Что я делаю не так?

ОБНОВЛЕНИЕ: чтобы создать идентификаторы в базе данных, я использую последовательность для каждой таблицы и триггер перед вставкой, чтобы получить следующее значение. Когда я создаю отдельный объект, например, встречу без гостей, он вставляется в базу данных и генерирует идентификатор.

Комментарии:

1. я сделал точно то же самое в EF, и это работает для меня. Первичные ключи в обеих таблицах являются автоматическими номерами. Я использую sql server для хранения данных

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

3. @MuhammadAdeelZahid Он использует Oracle, а не SQL Server

Ответ №1:

Решение этой проблемы:

«Поля идентификаторов, которые генерируются из последовательностей, не будут обрабатываться правильно. После сохранения объектов идентификаторы будут возвращены как 0. Я исправлю это, вручную взломав SSDL (откройте ваш файл .edmx в текстовом редакторе) с атрибутами StoreGeneratedPattern=»Identity» в полях ID (строки 6 и 16). Обратите внимание, что разработчик может удалить это изменение при будущих модификациях.

Хотя я полагаю, что это не является абсолютно необходимым, также может быть разумным изменить некоторые метаданные типа, такие как изменение «number»s на «int»s в вашем SSDL и «Decimal»s на «Int32» s в вашем CSDL, где это применимо. Часто они не генерируются автоматически с желаемыми значениями, особенно с помощью XE «.

@http://www.chrisumbel.com/article/oracle_entity_framework_ef

Комментарии:

1. <Имя типа объекта =»Виджет»> <Ключ> <Имя ссылки на свойство =»widgetID» /> </Key> <Имя свойства = «widgetID» StoreGeneratedPattern=»Идентификатор» Тип = «число» Обнуляемый = «false» Точность = «8» />

Ответ №2:

Что касается меня, проблема была решена простым открытием diagram .edmx и изменением свойства StoreGeneratedPattern с None на Identity для каждого первичного ключа в каждой таблице. После сохранения все было в порядке.

Я использую VS 2012, Entity Framework 5 (6 пока не поддерживается), Oracle 11.2, последний ODP.NET 12, .Net 4.5

Ответ №3:

В случае первого подхода с кодом EF, если эта ошибка возникает

(ORA-02291: нарушено ограничение целостности (FK_GUESTS_APPOINTMENTS) — родительский ключ не найден)

В моем случае есть 2 таблицы, в которых есть столбцы идентификаторов. Итак, я только что добавил

 [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
  

свойство для моего класса модели чуть выше столбца, который является столбцом идентификатора в базе данных, и это решило мою проблему 🙂

Надеюсь, это поможет 🙂

Ответ №4:

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

Комментарии:

1. Я использую последовательность и триггер, получающий следующее значение перед вставкой.

Ответ №5:

Вы вставляете запись со значением внешнего ключа, которое не найдено в родительской таблице, на которую ссылается ограничение.

Комментарии:

1. Ну, разве не supose Entity Framework для вставки назначения и гостя с помощью currect APPOINTMENT_ID FK?

2. Я не программист Java, поэтому я понятия не имею, что делает или не делает ваша entity framework. Если предполагается, что фреймворк сначала вставит родительский элемент, возможно ли, что вам нужно выполнить дополнительные настройки для вашего объекта? Глядя на ваш код, если я правильно его читаю, вы создаете ГОСТЯ перед ВСТРЕЧЕЙ с ГОСТЕМ. APPOINTMENT_ID является внешним ключом для возврата к НАЗНАЧЕНИЮ. НАЗНАЧЕНИЕ_ID. При создании ГОСТЕВОГО объекта есть ли у вас запись в таблице НАЗНАЧЕНИЙ с APPOINTMENT_ID=1?

3. Обнаружил проблему. Это была проблема с отображением… Вам нужно внести несколько изменений в сгенерированное сопоставление, чтобы иметь возможность это сделать. EF не нравится Oracle xD