为什么DbSet Add返回实体实例而不是void?

Nat*_*han 14 c# entity-framework entity-framework-6

所述DbSet <TEntity>.新增方法返回的实体.我通常期望一个Add操作有一个void返回类型.

当我查看EntityFramework源代码时,我看到以下实现:

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

        GetInternalSetWithCheck("Add").Add(entity);
        return entity;
    }
Run Code Online (Sandbox Code Playgroud)

GetInternalSetWithCheck 返回一个 InternalSet<TEntity>

有趣的Add方法InternalSet<TEntity>在其签名中有一个void返回类型:

public virtual void Add(object entity)
Run Code Online (Sandbox Code Playgroud)

我担心的是,当我对实体进行修改时,是否需要注意它与添加到DbSet的时间有关.

例如,有哪些情况

var entity = new MyEntity();
_dbSet.Add(entity);
entity.SomeDatModifyingMethod();
_dbContext.SaveChanges();
Run Code Online (Sandbox Code Playgroud)

可能会给出不同的行为

var entity = new MyEntity();
entity.SomeDatModifyingMethod();
_dbSet.Add(entity);
_dbContext.SaveChanges();
Run Code Online (Sandbox Code Playgroud)

或不同的行为:

var entity = new MyEntity();
entity = _dbSet.Add(entity);
entity.SomeDatModifyingMethod();
_dbContext.SaveChanges();
Run Code Online (Sandbox Code Playgroud)

在基本的默认实现中,它并不重要,因为它总是返回完全相同的实例.但是,Add方法是virtual,所以它可以被覆盖(虽然在公共源代码中,唯一的覆盖是测试双 - 但我不确定源代码实际上包括例如SqlServer支持实现).

为什么DbSet Add返回实体实例而不是void?

小智 6

它允许您编写"查找或添加"模式

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


Joh*_*ers 5

TEntity是引用类型,因此添加到的InternalSet<T>将是对实体的引用,而不是值。在将实体添加到集合之前或之后更改实体的内容都没有关系,因为它从未在数据库中创建。一种或另一种方式,INSERT将执行一个或等效方式。

至于为什么Add返回TEntity,它期望是因为它允许类似以下内容:

_dbSet.Add(new MyEntity()).SomeDatModifyingMethod();
_dbContext.SaveChanges();
Run Code Online (Sandbox Code Playgroud)