Почему 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"
});