Я недавно работал с Entity Framework 4 и немного не понимаю, когда использовать ObjectSet.Attach и ObjectSet.AddObject .
Из моего понимания:
- Используйте "Прикрепить", если объект уже существует в системе
- Используйте «AddObject» при создании новой сущности.
Итак, если я создаю нового человека , я делаю это.
var ctx = new MyEntities();
var newPerson = new Person { Name = "Joe Bloggs" };
ctx.Persons.AddObject(newPerson);
ctx.SaveChanges();
Если я изменяю существующего человека , я делаю следующее:
var ctx = new MyEntities();
var existingPerson = ctx.Persons.SingleOrDefault(p => p.Name = "Joe Bloggs" };
existingPerson.Name = "Joe Briggs";
ctx.SaveChanges();
Имейте в виду, это очень простой пример. На самом деле я использую Pure POCO (без генерации кода), шаблон репозитория (не работайте с ctx.Persons) и Unit of Work (не работайте с ctx.SaveChanges). Но «под прикрытием» в моей реализации происходит то, что описано выше.
Теперь мой вопрос - мне еще предстоит найти сценарий, в котором мне пришлось бы использовать Attach .
Что мне здесь не хватает? Когда нам нужно использовать Attach?
РЕДАКТИРОВАТЬ
Чтобы прояснить, я ищу примеры, когда использовать Attach over AddObject (или наоборот).
РЕДАКТИРОВАТЬ 2
Приведенный ниже ответ правильный (который я принял), но подумал, что добавлю еще один пример, в котором будет полезно Attach.
В моем приведенном выше примере для изменения существующего человека фактически выполняются два запроса.
Один для получения Person (.SingleOrDefault), а другой для выполнения ОБНОВЛЕНИЯ (.SaveChanges).
Если (по какой-то причине) я уже знал, что «Блог Джо» существует в системе, зачем делать дополнительный запрос, чтобы сначала получить его? Я мог сделать это:
var ctx = new MyEntities();
var existingPerson = new Person { Name = "Joe Bloggs" };
ctx.Persons.Attach(existingPerson);
ctx.SaveChanges();
Это приведет к выполнению только оператора UPDATE.
источник
Ответы:
ObjectContext.AddObject и ObjectSet.AddObject : AddObject метод для добавления нового созданных объектовкоторые не существуют в базе данных. Сущность получит автоматически сгенерированный временный ключ EntityKey, а для его EntityState будет установлено значение Added . Когда вызывается SaveChanges, для EF будет ясно, что эту сущность необходимо вставить в базу данных.
ObjectContext.Attach и ObjectSet.Attach :
с другой стороны, Attach используется для сущностей, которые уже существуют в базе данных. Вместо того, чтобы устанавливать для EntityState значение Added, Attach приводит к Unchanged EntityState, что означает, что оно не изменилось с момента присоединения к контексту. Предполагается, что присоединяемые объекты существуют в базе данных. Если вы изменяете объекты после того, как они были присоединены, при вызове SaveChanges значение EntityKey используется для обновления (или удаления) соответствующей строки путем нахождения соответствующего идентификатора в таблице db.
Кроме того, используя метод Attach, вы можете определить отношения между сущностями, которые уже существуют в ObjectContext, но имеютне было подключено автоматически. По сути, основная цель Attach - подключить сущности, которые уже прикреплены к ObjectContext и не являютсяновыми, поэтому вы не можете использовать Attach для присоединения сущностей, для которых EntityState добавлен. В этом случаевы должны использовать Add () .
Например, предположим, что у вашей сущности Person есть свойство навигации с именем Addresses, которое является коллекциейсущности Address . Допустим, вы прочитали оба объекта из контекста, но они не связаны друг с другом, и вы хотите сделать это таким:
источник
Это запоздалый ответ, но он может помочь другим, которые его найдут.
По сути, «отключенная» сущность может произойти, когда вы манипулируете сущностью вне области «использования».
Если вы войдете в другую область «using», то переменная «e» будет отключена, потому что она принадлежит предыдущей области «using», а поскольку предыдущая область «using» уничтожена, то «e» отключается.
Вот как я это понимаю.
источник
Это цитата из Programming Entity Framework: DbContext
источник
А как насчет ссылки только на первичный ключ вместо присоединения?
то есть:
источник