Entity Framework Core中的上下文DbContext类包含了一个ChangeTracker类,处于Microsoft.EntityFrameworkCore.ChangeTracking
的命名空间,其负责跟踪使用相同的检索每个实体的状态的DbContext
实例。它不打算直接在您的应用程序代码中使用它,因为它可能在将来的版本中更改。但是,您可以使用某些方法进行跟踪。
EF Core中 ChangeTracker类
在使用DbContext
后立即开始跟踪所有实体,直到它们超出作用域。EF 跟踪应用于所有实体及其属性的所有更改,以便它可以构建和执行适当的DML语句到底层数据源。
任何时间点的实体都具有以下状态之一,由Microsoft.EntityFrameworkCore.EntityState
EF Core中的枚举表示。
- Added
- Modified
- Deleted
- Unchanged
- Detached
让我们看看如何EntityState
根据对实体执行的操作自动更改。
状态未改变(Unchanged State )
首先,使用直接SQL查询或LINQ到实体查询检索的所有实体都将具有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()} ");
}
}
输出:Entity: Student, State: Unchanged
添加状态(Added State)
在DbContext
使用Add()
或Update()
方法中添加的所有没有键属性值的新实体都将标记为已添加。
using (var context = new SchoolContext())
{
context.Add(new Student() { FirstName = "Bill", LastName = "Gates" });
DisplayStates(context.ChangeTracker.Entries());
}
输出:Entity: Student, State: Added
修改状态(Modified State)
如果实体的任何属性的值在范围内更改DbContext
,则它将被标记为已修改状态。
using (var context = new SchoolContext())
{
var student = context.Students.First();
student.LastName = "LastName changed";
DisplayStates(context.ChangeTracker.Entries());
}
输出:Entity: Student, State: Modified
删除状态(Deleted State)
如果从DbContext
使用DbContext.Remove
或DbSet.Remove
方法中删除任何实体,则它将被标记为已删除。
using (var context = new SchoolContext())
{
var student = context.Students.First();
context.Students.Remove(student);
DisplayStates(context.ChangeTracker.Entries());
}
输出:Entity: Student, State: Modified
分离状态(Detached State)
从当前DbContext
实例的范围中创建或检索的所有实体都将具有“已分离”状态。它们也称为无连接的实体,并且不会被现有DbContext
实例跟踪。
var disconnectedEntity = new Student() { StudentId = 1, Name = "Bill" };
using (var context = new SchoolContext())
{
Console.Write(context.Entry(disconnectedEntity).State);
}
输出:Detached
在上面的示例中,disconnectedEntity
是在DbContext
实例(context)的范围之外创建的。因此,它处于Detached状态的上下文中。