Why does DbSet Add return an entity instance instead of void?

c# entity-framework entity-framework-6

Question

The DbSet<TEntity>.Add method returns an entity. I would normally have expected an Add operation to have a void return type.

When I look at the EntityFramework source code, I see the following implementation:

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

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

GetInternalSetWithCheck returns an InternalSet<TEntity>

The Add method of InternalSet<TEntity> interestingly enough has a void return type in its signature:

public virtual void Add(object entity)

My concern is whether or not I need to be careful with when I do modifications to an entity with relation to when it is added to a DbSet.

E.g. are there cases where

var entity = new MyEntity();
_dbSet.Add(entity);
entity.SomeDatModifyingMethod();
_dbContext.SaveChanges();

might give different behavior than

var entity = new MyEntity();
entity.SomeDatModifyingMethod();
_dbSet.Add(entity);
_dbContext.SaveChanges();

or different behavior than:

var entity = new MyEntity();
entity = _dbSet.Add(entity);
entity.SomeDatModifyingMethod();
_dbContext.SaveChanges();

In the basic default implementation, it wouldn't ever matter, because it just always returns exactly the same instance. However, the Add method is virtual, so it can be overridden (though in the public source code, the only override is a test double - but I'm not sure that source code actually includes e.g. the SqlServer support implementation).

Why does DbSet Add return an entity instance instead of void?

Accepted Answer

TEntity is a reference type, so what gets added to the InternalSet<T> will be a reference to the entity, not the value. It doesn't matter whether you change the contents of the entity before or after it is added to the set, since it has never been created in the database. One way or another, an INSERT or the equivalent will be performed.

As to why Add returns TEntity, it expect it's because it permits things like:

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

Popular Answer

It allows you to write a "Find or Add" pattern

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



Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why