У меня есть приложение ASP.NET MVC, использующее Entity Framework.Я разработал 2 модели, используя подход базы данных (код) для базы данных SQL Server 2008 R2.Одна модель по сути является родительской моделью, а другая - дочерней моделью, которая содержит внешний ключ для столбца, сгенерированного базой данных родительской модели.
Псевдокод:
CREATE TABLE PARENT
(
ROWID BIGINT IDENTITY(1,1) NOT NULL,
VALUE NVARCHAR(255) NOT NULL,
PRIMARY KEY(ROWID)
);
CREATE TABLE CHILD
(
ROWID BIGINT IDENTITY(1,1) NOT NULL,
PARENT_ROWID BIGINT NOT NULL,
VALUE NVARCHAR(255) NOT NULL,
PRIMARY KEY(ROWID),
FOREIGN KEY(PARENT_ROWID) REFERENCES PARENT(ROWID)
);
Всеэто работает нормально, и я могу связать свои данные с моей моделью и редактировать поля и так далее.У меня вопрос: если я пытаюсь создать записи для этих моделей, как я могу это сделать, когда внешний ключ для CHILD находится в PARENT, который еще не доступен, если я создаю их одновременно?
Итак, мои текущие основные шаги:
- Получить список
PARENT
моделей для вставки в базу данных - Вставка
PARENT
моделей Звоните SaveChanges()
Для каждого РОДИТЕЛЯ:
- Получить FK для РОДИТЕЛЯ
- Получить список моделей ДЕТЯМ для вставкив базу данных
- Для каждой модели РЕБЕНКА вставьте РЕБЕНКА с этим FK
- Вызов
SaveChanges()
Дополнительные операции и обновления базы данных для других моделей
- Вызов
SaveChanges()
Я уверен, что мог бы оптимизировать это, но это не то, что меня беспокоит.Мне кажется, что должен быть какой-то способ сделать это без ручного поиска FK или ручной настройки FK.Если мне нужно, я могу сделать это, но я бы хотел использовать только один вызов SaveChanges()
для передачи этих команд в одной транзакции.Я ищу что-то вроде:
Получить список моделей PARENT для вставки в базу данных
- Для каждого РОДИТЕЛЯ
- Вставить PARENT и вернуть новый FK (без сохранения)
- Получить список моделей CHILD для вставки в базу данных
- Для каждой модели CHILD вставить CHILD с этим FK
Дополнительные операции и обновления базы данных для других моделей
- Вызов
SaveChanges()
КомуЕсли предоставить некоторый контекст, в моей фактической таблице есть много столбцов, которые не гарантированно являются уникальными (именно поэтому PK имеет ROWID), и каждая из этих строк имеет отношения «нет ко многим» с дочерней таблицей, где дочерняя таблица такжеможет иметь неуникальные строки.Не очень идеально, но это то, чего требуют наши операции сейчас.Я включил здесь псевдокод, потому что реальный код проприетарный, но я мог бы создать реальный макет, если это необходимо.
Есть предложения?
Спасибо
РЕДАКТИРОВАТЬ: Поэтому я изменил свой код, чтобы использовать свойство навигации, как предложено.Это почти работает.Вот мой код:
List<PARENT> parents = getParents();
List<CHILD> children = getChildren();
foreach (PARENT parent in parents)
{
db.PARENT.add(parent);
foreach (CHILD child in children)
{
child.PARENT = parent;
db.CHILD.add(child);
}
}
db.SaveChanges();
На первый взгляд, это именно то, что я искал.Однако, когда я запускаю его, дочерние записи вставляются только для первой родительской записи.Так, например, если у меня есть 3 записи PARENT и 3 записи CHILD, у меня должно быть 9 новых записей в моей таблице CHILD.Однако после этого кода у меня есть только 3 записи для первого РОДИТЕЛЯ.
Я предполагаю, что это как-то связано с тем, что я неоднократно использую один и тот же список детей, и Entity Framework просматривает их как дубликаты.Я переместил его в цикл PARENT for следующим образом, и он работает как положено:
List<PARENT> parents = getParents();
foreach (PARENT parent in parents)
{
db.PARENT.add(parent);
List<CHILD> children = getChildren();
foreach (CHILD child in children)
{
child.PARENT = parent;
db.CHILD.add(child);
}
}
db.SaveChanges();
Но я бы предпочел этого не делать, поскольку функция getChildren () довольно громоздка.Есть мысли?