【问题标题】:How change tracking works in Entity Framework实体框架中更改跟踪的工作原理
【发布时间】:2017-05-15 21:52:31
【问题描述】:

鉴于以下代码,EF/DbContext 如何知道对 customer 对象所做的更改:

class Program
{
    static void Main()
    {
        using(var shopContext = new ShopContext())
        {
            var customer = shopContext.Customers.Find(7);

            customer.City = "Marion";

            customer.State = "Indiana";

            shopContext.SaveChanges();
        }
    }
}

public class ShopContext : DbContext
{
    public DbSet<Customer> Customers { get; set; }
}

public class Customer
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string City { get; set; }
    public string State { get; set; }
}

谢谢

【问题讨论】:

标签: c# entity-framework-4 dbcontext change-tracking


【解决方案1】:

当您从上下文加载实体时,它会保留一个额外的数据结构 - 我们称之为条目。该条目包含两组值 - 原始值和当前值。当您执行SaveChanges 操作时,EF 会遍历您的客户实体并更新条目中的当前值,以便它们与您的实体的真实状态相匹配 - 此操作称为检测更改。在 SQL 命令生成期间,EF 将比较当前值和原始值并构建 SQL 更新语句来修改数据库中更改的值。此操作称为快照更改跟踪 - EF 在条目中保留快照。

还有一种称为动态更改跟踪的替代方法,它会在您将值分配给实体属性的同时修改条目中的当前值。动态更改跟踪具有特定要求(例如实体中的所有属性都必须是 virtual),因为它必须在运行时将您的类包装到动态代理中。这曾经是首选方式,但由于复杂场景中的一些性能问题,目前应该默认使用快照更改跟踪。

【讨论】:

  • 嗨,上下文如何知道客户对象?它是如何连接/链接的?
  • Context 知道这一点,因为您通过调用Customers.Find,通过相同的上下文实例检索了客户对象
  • @Ladislav:您的最后一句话是否意味着代理更改跟踪在某些情况下的性能比快照更改跟踪更差?你知道例子吗?我一直认为代理更改跟踪在任何情况下都更快......
  • @Slauma:检查this article。 Arthur 是 EF 开发人员的成员。如果您检查 ADO.NET 团队或 DbContext 生成器模板提供的每个代码优先示例,您将看到更改跟踪代理不再是默认行为。通过切换到更改跟踪代理,快照更改跟踪的性能问题似乎更容易识别和解决。
  • @Ladislav:感谢您的参考!我不得不编辑一个过分赞扬变更跟踪代理的旧答案。
猜你喜欢
  • 2011-04-23
  • 1970-01-01
  • 2014-12-08
  • 2011-10-27
  • 1970-01-01
  • 1970-01-01
  • 2012-10-26
  • 2011-09-09
  • 1970-01-01
相关资源
最近更新 更多