变更跟踪如何在Entity Framework中运行

Yai*_*vet 37 c# change-tracking entity-framework-4 dbcontext

鉴于以下代码,EF/DbContext如何了解对客户对象所做的更改:

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; }
}
Run Code Online (Sandbox Code Playgroud)

谢谢

Lad*_*nka 52

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

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

  • @Slauma:查看[本文](http://blog.oneunicorn.com/2011/12/05/should-you-use-entity-framework-change-tracking-proxies/).Arthur是EF dev的成员.团队如果您检查ADO.NET团队或DbContext生成器模板提供的每个代码的第一个示例,您将看到更改跟踪代理不再是默认行为.通过切换到更改跟踪代理,可以更轻松地识别和解决快照更改跟踪的性能问题. (2认同)