Entity Framework(5)是否对尚未实际编辑的实体执行UPDATE

时间:2013-12-27 14:45:16

标签: c# entity-framework-5

最近我和一位Java程序员交谈,他告诉我Hibernate足够智能,可以检测实体是否对其进行了任何更改,即使您调用了UPDATE对于实体,如果尚未修改,则不会执行SQL UPDATE命令。

我没有处理大量数据,但我仍然很好奇,如果同样适用于Entity Framework 5。在我当前的项目中,我使用Repositories,因此Update方法如下所示:

public virtual void Update(TEntity entity)
    {
        dbSet.Attach(entity);
        context.Entry(entity).State = EntityState.Modified;
        context.SaveChanges();
    }

这与UnitOfWork相结合,假设我刚刚向控制器提交了List NewsNews,其中public ActionResult Edit(List<News> model) { foreach (News item in model) { unitOfWork.NewsRepository.Update(item); } } 是一个实体。因此,如果在我的行动中我做了类似的事情:

{{1}}

如果我有未修改的项目,会发生什么?我是否仍然使用相同的数据进行数据库查询来更新记录,或者实体框架是否足够智能,只是跳过它并继续下一个项目?

2 个答案:

答案 0 :(得分:1)

实体框架跟踪对象在附加到上下文时所做的更改,如果您对属性进行了更改,则会发出UPDATE语句,并调用SaveChanges,而无需设置{ {1}}手动State

在代码中,当对象未附加到上下文时,您正在进行更改。实体框架可以让这项工作的唯一方法是强制EntityState.Modified语句(重新)设置数据库中的所有字段,即使是那些保持不变的字段。

所以,是的,一般来说,同样适用于实体框架,而不是你如何使用它。

答案 1 :(得分:1)

为了获得将投影到数据库的实际查询的更改集,您可以查询基础上下文或实体本身(如果它是自我跟踪实体)。 (请参阅此问题answer)。

从您的示例中不清楚您是否正在使用POCO或自我跟踪实体,但在这两种情况下,您都错过了在附加对象时弄清楚对象中已更改内容的步骤。

为了做到这一点,EF应该为db查询原始对象并与附加的对象进行比较,或者如果它是自我跟踪实体,EF将查询内部实体变更集以进行更新。

更新:为了总结@hvd和我说的话:

由于我们在谈论POCO实体,所以会发生以下情况:

  1. 创建新上下文并加载实体。
  2. 对对象进行了更改 - 上下文仍保留变更集
  3. 处理上下文,因此更改集丢失
  4. 创建新上下文并将实体附加到上下文,并将EntityState设置为Modified,因此上下文包含所有已修改的字段
  5. 你可以做几件事

    • 切换到自我跟踪实体
    • 序列化 - 反序列化上下文,以便变更集将保持
    • 为原始对象重新查询数据库
    • 将原始对象保留在某处并更新它,而不是仅仅附加已更改并将EntityState设置为Modified,即根据更改的实体在上下文中进行更改。

    Pluralsight上有这个course(并且它有两个较新版本,具有不同的客户端技术堆栈),涵盖了这些主题,并展示了如何在必须更改实体的情况下进行更改跟踪