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

时间:2014-01-26 03:18:02

标签: c# entity-framework entity-framework-6

DbSet<TEntity>.Add方法返回一个实体。我通常希望Add操作具有void返回类型。

当我查看EntityFramework source code时,我会看到以下实现:

    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的时间有关。

E.g。是否存在

的情况
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?

2 个答案:

答案 0 :(得分:6)

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

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

答案 1 :(得分:5)

TEntity是一种引用类型,因此添加到InternalSet<T>的内容将是实体的引用,而不是值。在将实体添加到集合之前或之后更改实体的内容并不重要,因为它从未在数据库中创建过。不管怎样,都会执行INSERT或等价物。

至于Add返回TEntity的原因,它预计会因为它允许以下内容:

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