Почему 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 TEntity Add(TEntity entity)
    {
        Check.NotNull(entity, "entity");

        GetInternalSetWithCheck("Add").Add(entity);
        return entity;
    }

Моя забота заключается в том, нужно ли мне быть осторожным, когда я вношу изменения в объект, связанный с тем, когда он добавляется в DbSet.

Например, существуют случаи, когда

    public virtual TEntity Add(TEntity entity)
    {
        Check.NotNull(entity, "entity");

        GetInternalSetWithCheck("Add").Add(entity);
        return entity;
    }

может привести к

    public virtual TEntity Add(TEntity entity)
    {
        Check.NotNull(entity, "entity");

        GetInternalSetWithCheck("Add").Add(entity);
        return entity;
    }

или другое поведение, чем:

    public virtual TEntity Add(TEntity entity)
    {
        Check.NotNull(entity, "entity");

        GetInternalSetWithCheck("Add").Add(entity);
        return entity;
    }

В основной реализации по умолчанию это никогда не имеет значения, потому что она всегда возвращает точно такой же экземпляр. Тем не менее, метод 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
Является ли этот КБ законным? Да, узнайте, почему