#asp.net-mvc #entity-framework #foreign-key-relationship
Вопрос:
Я хочу создать новую строку в своей базе данных в таблице, в которой есть несколько связей с внешними ключами, и я не смог понять, в каком порядке и какие вызовы необходимо выполнить. Это то, что у меня есть до сих пор:
db.Models.Order order = DB.Models.Order.CreateOrder( apple );
order.CustomerReference.Attach( ( from c in db.Customer where c.Id == custId select c ).First() );
db.SaveChanges();
Код не работает во второй строке там, говоря:
Присоединение не является допустимой операцией, если исходный объект, связанный с этим связанным концом, находится в добавленном, удаленном или отсоединенном состоянии. Объекты, загруженные с помощью опции слияния без блокировки, всегда отсоединяются.
Есть какие-нибудь идеи?
Ответ №1:
(Спасибо Джону за исправления грамматики)
Так что я все понял. Это то, что вы должны сделать:
db.Models.Order order = DB.Models.Order.CreateOrder( apple );
order.Customer = (from c in db.Customer where c.Id == custId select c).First();
db.SaveChanges();
Я надеюсь, что это поможет людям.
Ответ №2:
Почему бы не использовать ссылки на сущности? Ваш метод вызовет дополнительное SELECT
утверждение.
Гораздо более приятный способ-использовать CustomerReference
класс и ан EntityKey
.
order.CustomerReference = new System.Data.Objects.DataClasses.EntityReference<Customers>();
order.CustomerReference.EntityKey = new EntityKey("ModelsEntities.Customers", "Id", custId);
Комментарии:
1. Я бы не возражал использовать ваше решение, но я хотел бы использовать строго типизированные имена столбцов базы данных, чтобы я мог получать ошибки во время компиляции, если связь недопустима.
2. Я согласен с Кирком Макферсоном, его способ позволяет избежать дополнительного ВЫБОРА. Я предполагаю, что вы цените ремонтопригодный код выше производительности. Вы все еще можете использовать его способ, но вместо жестко закодированных строк вы можете использовать отражение для генерации строк, получая имена классов для моделей и клиентов в приведенном выше примере. Таким образом, вы получите как на один выбор меньше, так и сильные ошибки ввода / компиляции. Дополнительные накладные расходы из-за отражения не должны быть проблемой, ИМО.
3. Хорошо, вы можете использовать отражение для создания имени набора сущностей, но не имени ключа (т. Е. Можете создавать «Модели». Клиенты» с использованием строгого набора текста). Есть ли способ сгенерировать «идентификатор» с помощью отражения?
Ответ №3:
Для обновления вот несколько примеров кода:
using (var ctx = new DataModelEntities())
{
var result = (from p in ctx.UserRole.Where(o => o.UserRoleId == userRole.UserRoleId)
select p).First();
result.RolesReference.EntityKey = new EntityKey("DataModelEntities.Roles",
"RoleId", userRole.RoleId);
result.UserRoleDescription = userRole.UserRoleDescription;
ctx.SaveChanges();
}