Почему DbSet Add возвращает экземпляр объекта вместо void?

c# entity-framework entity-framework-6

Вопрос

Метод 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?

Принятый ответ

TEntity является ссылочным типом, поэтому то, что добавляется к InternalSet<T> будет ссылкой на объект, а не на значение. Неважно, измените ли вы содержимое объекта до или после его добавления в набор, поскольку оно никогда не создавалось в базе данных. Так или иначе, будет выполнен INSERT или эквивалент.

Что касается того, почему Add возвращает TEntity , он ожидает, что это происходит потому, что он позволяет такие вещи, как:

_dbSet.Add(new MyEntity()).SomeDatModifyingMethod();
_dbContext.SaveChanges();

Популярные ответы

Это позволяет вам написать шаблон «Найти или добавить»

var person = context.People.Find(ssn) ?? context.People.Add(new Person
{
   SocialSecurityNumber = ssn,
   FirstName = "John",
   LastName = "Doe"
});



Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему