46

给定以下代码,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; }
}

谢谢

4

1 回答 1

65

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

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

于 2012-04-30T07:28:11.010 回答