Вставьте запись в дочернюю таблицу, когда родительская запись уже существует, сначала используя код Entity Framework - PullRequest
6 голосов
/ 02 августа 2011

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

  1. Извлечение родительских (A) записей
  2. Создать новую дочернюю (B) запись
  3. Добавить родительскую запись в свойство Navigation объекта Child. B.A = A
  4. Вызов SaveChanges.

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

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

Нужно исправить это как можно скорее. Любая помощь будет принята с благодарностью.

Ответы [ 2 ]

18 голосов
/ 02 августа 2011

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

context.Parents.Attach(parent); // just attach as unchanged
context.Childs.Add(child); // add as inserted
parent.Childs.Add(child); // make connection between existing and inserted object
context.SaveChanges();

Другой подход может быть:

child.Parent = parent;
context.Childs.Add(child); // both child and parent are marked as inserted!!!
context.Entry(parent).State = EntityState.Unchanged; // set parent as unchanged
context.SaveChanges();
0 голосов
/ 15 апреля 2014

Кроме того, в случае, когда у вас есть что-то вроде:

public class B
{
[Key]
public int Id {get;set;}

public AId {get;set;}

//... other properties here

[ForeignKey("AId")]
public virtual A ParentA {get;set;}
}

Вы можете установить внешний ключ только для существующей записи A id в БД без него и оставить значение ParentA пустым, а на context.SaveChanges() он будет работать как положено (без создания другой записи A в БД).

...