В dbset.Attach (entity) vs DbContext.Запись (сущность).State = EntityState.Модифицированный
когда я нахожусь в отдельном сценарии и получаю dto от клиента, который я сопоставляю с сущностью, чтобы сохранить его, я делаю это:
context.Entry(entity).State = EntityState.Modified;
context.SaveChanges();
что-то DbSet.Attach(entity)
или почему я должен использовать .Прикрепите метод, когда EntityState.Изменено уже прикрепляет сущность?
2 ответов:
когда вы
context.Entry(entity).State = EntityState.Modified;, вы не только присоединение объектаDbContext, вы также отмечаете всю сущность как грязную. Это означает, что когда вы делаетеcontext.SaveChanges(), EF создаст инструкцию update, которая обновит все поля сущности.это не всегда желательно.
С другой стороны,
DbSet.Attach(entity)присоединяет объект к контексту без маркировка грязная. Это эквивалентно делатьcontext.Entry(entity).State = EntityState.Unchanged;при присоединении таким образом, если вы не перейдете к обновлению свойства на сущности, при следующем вызове
context.SaveChanges(), EF не будет генерировать обновление базы данных для этого объекта.даже если вы планируете сделать обновление сущности, если сущность имеет много свойств (столбцы БД), но вы хотите обновить только несколько, вы можете найти это выгодным сделать
DbSet.Attach(entity), а потом только обновить несколько свойств, которые нуждаются в обновлении. Выполнение этого способа создаст более эффективный оператор обновления от EF. EF будет обновлять только те свойства, которые вы изменили (в отличие отcontext.Entry(entity).State = EntityState.Modified;что приведет к обновлению всех свойств / столбцов)соответствующие документы: добавить / присоединить и состояния сущностей.
пример кода
допустим, у вас есть следующая сущность:
public class Person { public int Id { get; set; } // primary key public string FirstName { get; set; } public string LastName { get; set; } }если ваш код выглядит так:
context.Entry(personEntity).State = EntityState.Modified; context.SaveChanges();в Сгенерированный SQL будет выглядеть примерно так:
UPDATE person SET FirstName = 'whatever first name is', LastName = 'whatever last name is' WHERE Id = 123; -- whatever Id is.обратите внимание, как приведенная выше инструкция update обновит все столбцы, независимо от того, действительно ли вы изменили значения или нет.
напротив, если ваш код использует" нормальный " прикрепить следующим образом:
context.People.Attach(personEntity); // State = Unchanged personEntity.FirstName = "John"; // State = Modified, and only the FirstName property is dirty. context.SaveChanges();тогда сгенерированный оператор обновления отличается:
UPDATE person SET FirstName = 'John' WHERE Id = 123; -- whatever Id is.как вы можете видеть, заявление об обновлении только обновления значения были фактически изменены после того, как вы прикрепили сущность к контексту. В зависимости от структуры таблицы это может оказать положительное влияние на производительность.
теперь, какой вариант лучше для вас, полностью зависит от того, что вы пытаетесь сделать.
при использовании
DbSet.Updateметод, Entity Framework помечает все свойства вашего объекта какEntityState.Modified, так их композиций. Если вы хотите изменить только некоторые из ваших свойств, не все из них, используйтеDbSet.Attach. Этот метод делает все ваши свойстваEntityState.Unchanged, Так что вы должны сделать ваши свойства, которые вы хотите обновитьEntityState.Modified. Таким образом, когда приложение попадает вDbContext.SaveChanges, он будет работать только с измененными свойствами.
Comments