Почему DbSet Add возвращает экземпляр объекта вместо void?
Метод DbSet <TEntity> .Add возвращает объект. Обычно я ожидал, что операция Add
будет иметь тип возврата void
.
Когда я смотрю исходный код EntityFramework, я вижу следующую реализацию:
public virtual TEntity Add(TEntity entity)
{
Check.NotNull(entity, "entity");
GetInternalSetWithCheck("Add").Add(entity);
return entity;
}
GetInternalSetWithCheck
возвращает InternalSet<TEntity>
Метод Add
InternalSet<TEntity>
достаточно интересен, имеет в своей сигнатуре тип возвращаемого значения void:
public virtual void Add(object entity)
Я забочусь о том, нужно ли мне быть осторожным, когда я вношу изменения в объект, связанный с тем, когда он добавляется в DbSet.
например. существуют случаи, когда
var entity = new MyEntity();
_dbSet.Add(entity);
entity.SomeDatModifyingMethod();
_dbContext.SaveChanges();
может давать другое поведение, чем
var entity = new MyEntity();
entity.SomeDatModifyingMethod();
_dbSet.Add(entity);
_dbContext.SaveChanges();
или другое поведение, чем:
var entity = new MyEntity();
entity = _dbSet.Add(entity);
entity.SomeDatModifyingMethod();
_dbContext.SaveChanges();
В основной реализации по умолчанию это никогда не имеет значения, потому что она всегда возвращает точно такой же экземпляр. Тем не менее, метод Add
virtual
, поэтому его можно переопределить (хотя в общедоступном исходном коде единственное переопределение - это двойной тест), но я не уверен, что исходный код действительно включает, например, реализацию поддержки SqlServer).
Почему DbSet Add возвращает экземпляр сущности вместо void?
Ответы
Ответ 1
TEntity
является ссылочным типом, поэтому то, что добавляется к InternalSet<T>
, будет ссылкой на объект, а не на значение. Неважно, измените ли вы содержимое объекта до или после его добавления в набор, поскольку оно никогда не создавалось в базе данных. Так или иначе, будет выполняться INSERT
или эквивалент.
Что касается того, почему Add
возвращает TEntity
, он ожидает этого, потому что он разрешает такие вещи, как:
_dbSet.Add(new MyEntity()).SomeDatModifyingMethod();
_dbContext.SaveChanges();
Ответ 2
Это позволяет вам написать шаблон "Найти или добавить"
var person = context.People.Find(ssn) ?? context.People.Add(new Person
{
SocialSecurityNumber = ssn,
FirstName = "John",
LastName = "Doe"
});