关于MySql使用EFCore CodeFirst 自定义RowVersion并发字段的解决办法

  • 2022-08-05 23:48:35

依赖包版本:mysql.entityframeworkcore v5.0.3.1

rowversion字段的作用:在增/删/改...数据时,先判断该数据的rowversion字段是否发生改变来实现乐观锁的效果。

在sqlserver中,设置并发字段时可以在代码中采用byte[]类型字段来存储数据库中timestamp类型的数据;

但在mysql中,rowversion需要应用程序赋值。这里存储guid值实现版本号控制。

  1. 定义并发控制字段

    public class adminentity
        {
        	//对应mysql数据库中的字段类型是varbinary(4000)
            public byte[] rowversion { get; set; }
        }
  2. 配置实体关系映射

    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()
                });
    	}
    

      

  3. 重写数据库上下文的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();
            }
  4. 检查生成的sql语句

    关于MySql使用EFCore CodeFirst  自定义RowVersion并发字段的解决办法

  5. 查看数据库的数据

    关于MySql使用EFCore CodeFirst  自定义RowVersion并发字段的解决办法

  6. 测试验证并发字段是否可用

    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();
                }
            }
  7. 执行结果

    关于MySql使用EFCore CodeFirst  自定义RowVersion并发字段的解决办法

     ok,说明并发字段起作用了。

猜你喜欢