使用乐观并发确保数据一致性
概述
在本指南中,您可以了解如何使用 EF Core 提供程序实现乐观并发控制。乐观并发控制确保在应用程序读取数据和将数据写回数据库之间,数据不会被覆盖。EF Core 提供程序支持两种实现乐观并发控制的方法:
并发令牌,通过使用
ConcurrencyCheck
属性或IsConcurrencyToken()
灵活 API 方法行版本,通过使用
Timestamp
属性或IsRowVersion()
灵活 API 方法
提示
我们建议每个实体仅使用上述实现方法之一来确保乐观并发。
并发令牌
您可以通过使用并发令牌来确保指定属性上的乐观并发。在查询实体时,EF Core 提供程序跟踪并发令牌。然后,当提供程序调用 SaveChanges()
或 SaveChangesAsync()
方法时,它会比较并发令牌的值与数据库中保存的值,以确保原始值未更改。
您可以通过在定义类时指定 ConcurrencyCheck
属性来配置并发令牌。以下示例展示了如何在一个 Customer
类的 LastModified
属性上指定 ConcurrencyCheck
属性
public class Customer { public ObjectId Id { get; set; } public String Name { get; set; } public String Order { get; set; } [ ] public DateTimeOffset LastModified { get; set; } }
您还可以使用 IsConcurrencyToken()
方法配置并发令牌。在 DbContext
类的 OnModelCreating()
方法中调用 IsConcurrencyToken()
方法,如下面的示例所示
protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.Entity<Customer>() .Property(p => p.LastModified) .IsConcurrencyToken(); }
EF Core 提供程序支持在驱动程序支持的任何属性类型上设置并发令牌。您还可以在单个实体上设置多个并发令牌。如果您需要更新并发令牌,则必须手动进行。
行版本控制
您可以通过使用行版本控制来确保乐观并发。行版本控制允许您通过指定一个在实体更改时自动增加的版本字段来跟踪实体的更改。您可以通过在定义类时指定 Timestamp
属性来配置行版本控制。以下示例显示了如何在 Customer
类的 Version
属性上指定 Timestamp
属性
public class Customer { public ObjectId Id { get; set; } public String Name { get; set; } public String Order { get; set; } [ ] public long Version { get; set; } }
您还可以使用 IsRowVersion()
方法来配置行版本控制。在 DbContext
类的 OnModelCreating()
方法中调用 IsRowVersion()
方法,如下所示
protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.Entity<Customer>() .Property(p => p.Version) .IsRowVersion(); }
EF Core 提供程序仅支持实体的单个属性上的行版本控制。该属性必须是 long
、int
、ulong
或 uint
类型。
限制
在配置与其他应用程序共享数据的数据库上的乐观并发控制时,请考虑以下限制
其他应用程序必须支持您在 Entity Framework Core 应用程序中使用的乐观并发控制机制。
其他应用程序必须在任何更新或删除操作期间支持对并发令牌和行版本字段的检查。
如果您正在使用行版本控制,则其他应用程序必须将行版本字段映射到属性名称后跟字符串:
_version
。应用程序必须为每次更新将字段的值增加 1。
附加信息
有关使用Entity Framework Core进行乐观并发控制的更多信息,请参阅乐观并发在Microsoft Entity Framework Core文档中。