Entity Framework Core系列教程-19-ChangeTracker(变更追踪器)

Entity Framework Core中的ChangeTracker(变更追踪器)

Entity Framework Core中的DbContext在Microsoft.EntityFrameworkCore.ChangeTracking命名空间中包含ChangeTracker类,该类负责跟踪使用同一DbContext实例检索的每个实体的状态。它不打算直接在您的应用程序代码中使用,因为它可能在将来的版本中更改。但是,您可以使用一些方法进行跟踪。

一旦使用DbContext检索了所有实体,Entity Framework Core中的ChangeTracker类就会开始跟踪所有实体,直到它们超出其范围。 EF跟踪应用于所有实体及其属性的所有更改,以便它可以为基础数据源生成并执行适当的DML语句。

实体在任何时间点都具有以下状态之一,这些状态由EF Core中的枚举Microsoft.EntityFrameworkCore.EntityState表示。

  • Added
  • Modified
  • Deleted
  • Unchanged
  • Detached

让我们看看如何根据对实体执行的操作自动更改EntityState:

Unchanged State(不变的状态)

首先,使用直接SQL查询或LINQ-to-Entities查询检索的所有实体都将具有“Unchanged”状态。

public static void Main()
{
    using (var context = new SchoolContext())
    {
        // retrieve entity 
        var student = context.Students.First();
        DisplayStates(context.ChangeTracker.Entries());
    }
}

private static void DisplayStates(IEnumerable<EntityEntry> entries)
{
    foreach (var entry in entries)
    {
        Console.WriteLine($"Entity: {entry.Entity.GetType().Name},
                             State: {entry.State.ToString()} ");
    }
}

Output:
Entity: Student, State: Unchanged

Added State(新增状态)

使用Add()或Update()方法在DbContext中添加的所有没有键属性值的新实体都将标记为“Added”。

using (var context = new SchoolContext())
{              
    context.Add(new Student() { FirstName = "Bill", LastName = "Gates" });
    
    DisplayStates(context.ChangeTracker.Entries());
}
Output:
Entity: Student, State: Added

Modified State(修改状态)

如果实体的任何属性的值在DbContext的范围内更改,则它将被标记为Modified状态。

using (var context = new SchoolContext())
{
    var student = context.Students.First();
    student.LastName = "LastName changed";
              
    DisplayStates(context.ChangeTracker.Entries());
}
Output:
Entity: Student, State: Modified

Deleted State(删除状态)

如果实体的任何属性的值在DbContext的范围内更改,则它将被标记为Modified状态。

using (var context = new SchoolContext())
{
    var student = context.Students.First();
    student.LastName = "LastName changed";
              
    DisplayStates(context.ChangeTracker.Entries());
}
Output:
Entity: Student, State: Modified

Deleted State(删除状态)

如果使用DbContext.Remove或DbSet.Remove方法从DbContext中删除了任何实体,则它将被标记为Deleted。

using (var context = new SchoolContext())
{
    var student = context.Students.First();
    context.Students.Remove(student);
    
    DisplayStates(context.ChangeTracker.Entries());
}
Output:
Entity: Student, State: Deleted

Detached State(分离状态)

在当前DbContext实例范围之外创建或检索的所有实体都将处于Detached状态。它们也称为断开连接的实体,现有的DbContext实例不会对其进行跟踪。

var disconnectedEntity = new Student() { StudentId = 1, Name = "Bill" };

using (var context = new SchoolContext())
{              
    Console.Write(context.Entry(disconnectedEntity).State);
}
Output:
Detached

在上面的示例中,disconnectedEntity是在DbContext实例(上下文)的范围之外创建的。因此,对于上下文,它处于Detached状态。

原文地址:https://www.cnblogs.com/AlexanderZhao/p/12878805.html