- A+
所属分类:.NET技术
依赖包版本:MySql.EntityFrameworkCore v5.0.3.1
RowVersion字段的作用:在增/删/改...数据时,先判断该数据的RowVersion字段是否发生改变来实现乐观锁的效果。
在SqlServer中,设置并发字段时可以在代码中采用byte[]类型字段来存储数据库中timestamp类型的数据;
但在MySql中,RowVersion需要应用程序赋值。这里存储Guid值实现版本号控制。
-
定义并发控制字段
public class AdminEntity { //对应MySql数据库中的字段类型是varbinary(4000) public byte[] RowVersion { get; set; } }
-
配置实体关系映射
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<AdminEntity>(entity => { entity.ForMySQLHasCharset("utf8"); entity.ForMySQLHasCollation("utf8_general_ci"); entity.ToTable("T_Admins"); entity.Property(e => e.RowVersion) .HasColumnName("rowVersion") .IsConcurrencyToken();//注意这里要使用IsConcurrencyToken()而不是IsRowVersion() }); }
-
重写数据库上下文的SaveChanges()方法
public override int SaveChanges() { //检查数据库更改 this.ChangeTracker.DetectChanges(); //筛选新增/修改的实体对象 var modifiedEntities = this.ChangeTracker .Entries() .Where(x => x.State == EntityState.Modified || x.State == EntityState.Added) .Select(x => x.Entity) .ToList(); foreach (var entity in modifiedEntities) { //存储一个新的Guid值 entity?.GetType().GetProperty("RowVersion") ?.SetValue(entity, Encoding.Default.GetBytes(Guid.NewGuid().ToString())); } return base.SaveChanges(); }
-
检查生成的Sql语句
-
查看数据库的数据
-
测试验证并发字段是否可用
public void Test() { using (MyDbContext db = new MyDbContext()) { var admin1 = db.AdminSet.FirstOrDefault(); admin1.AdminName = "admin11"; using (zzmqDbContext db2 = new zzmqDbContext()) { var admin2 = db2.AdminSet.FirstOrDefault(); admin2.AdminName = "admin22"; db2.SaveChanges(); } db.SaveChanges(); } }
-
执行结果
ok,说明并发字段起作用了。