依赖包版本: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,说明并发字段起作用了。
黄山市民网:https://www.huangshanshimin.com/