【问题标题】:Why does DbSet Add return an entity instance instead of void?为什么 DbSet Add 返回一个实体实例而不是 void?
【发布时间】:2014-01-26 03:18:01
【问题描述】:

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&lt;TEntity&gt;

有趣的是,InternalSet&lt;TEntity&gt;Add 方法在其签名中有一个 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?

【问题讨论】:

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


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

      至于为什么Add 返回TEntity,它期望是因为它允许这样的事情:

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

      【讨论】:

      • 这很有道理——只要Add 方法永远不会做类似返回代理之类的事情——也许是为了更改跟踪? - 在这种情况下,添加后重新分配参考可能很重要? (例如最后一个代码示例)
      • 虽然想起来了,但我不知道您为什么需要更改跟踪新添加的实体...
      • Add 可能不是SaveChanges 之前的最后一次更改。如果有Remove 怎么办?
      • 对不起,当我说它不需要对添加的实体进行更改跟踪时,我的意思是它不需要跟踪添加的实体,除了它被添加的事实 - 这意味着即使您使用的是 EF 代理更改跟踪,似乎也没有理由 Add 需要“代理”添加的实体(以跟踪单个属性更改) - 因此,您的声明相信返回实体只是用于方法链。
      猜你喜欢
      • 2023-03-07
      • 2020-12-14
      • 1970-01-01
      • 1970-01-01
      • 2017-04-26
      • 2019-05-31
      • 2017-01-20
      • 2016-01-21
      • 2020-12-29
      相关资源
      最近更新 更多