mysql timestamp 并发_MySQL 实现 EF Code First TimeStamp/RowVersion 并发控制

在将项目迁移到MySQL 5.6.10数据库上时,遇到和迁移到PostgreSQL数据库相同的一个问题,就是TimeStamp/RowVersion并发控制类型在非Microsoft SQL Server数据库中的实现。

先上网搜索解决方案,找到Ak.Ini的博文http://www.cnblogs.com/akini/archive/2013/01/30/2882767.html,于是尝试使用文中介绍的方法。

项目中有一个类要解决并发更新的问题,该类定义:

public classStock

{public int Id { get; set; }

[Required(ErrorMessageResourceName= "Generic_Required", ErrorMessageResourceType = typeof(ValidationMessage))]public Location Location { get; set; }

[Required(ErrorMessageResourceName= "Generic_Required", ErrorMessageResourceType = typeof(ValidationMessage))]public Part Part { get; set; }public Batch Batch { get; set; }

[Required(ErrorMessageResourceName= "Generic_Required", ErrorMessageResourceType = typeof(ValidationMessage))]public int Quantity { get; set; }

[Required(ErrorMessageResourceName= "Generic_Required", ErrorMessageResourceType = typeof(ValidationMessage))]public int UpdatedBy { get; set; }

[Required(ErrorMessageResourceName= "Generic_Required", ErrorMessageResourceType = typeof(ValidationMessage))]public DateTime UpdatedTime { get; set; }public DateTime RowVersion { get; set; }

}

其中最后一个属性是用作并发控制的,MySqlMigrationSqlGenerator不允许byte[]类型上标记TimeStamp/RowVersion,这里使用DateTime类型。

这是EF生成的Stocks表定义:

> DESCkit.Stocks+ ---------- + --------- + --------- + -------- + ------------ + ---------- +

| Field | Type | Null | Key | Default | Extra |

+ ---------- + --------- + --------- + -------- + ------------ + ---------- +

| Id | int(11) | NO | PRI | | auto_increment |

| Quantity | int(11) | NO | | | |

| UpdatedBy | int(11) | NO | | | |

| UpdatedTime | datetime | NO | | | |

| RowVersion | datetime | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |

| Location_Id | int(11) | NO | MUL | | |

| Part_PartNo | varchar(50) | NO | MUL | | |

| Batch_BatchNo | varchar(50) | YES | MUL | | |

+ ---------- + --------- + --------- + -------- + ------------ + ---------- +

8 rows

然后在DbContext的构造器中加入下面修改DbModelBuilder的代码:

protected override voidOnModelCreating(DbModelBuilder modelBuilder)

{

modelBuilder.Conventions.Remove();

modelBuilder.Conventions.Remove();

modelBuilder.Entity().Property(p =>p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

modelBuilder.Entity().Property(p =>p.RowVersion).IsConcurrencyToken().HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

}

上面代码中前两行是为了禁用EF级联删除的特性,可以参考我以前的博文:http://www.cnblogs.com/jlzhou/archive/2012/03/13/2394333.html

后两行显式声明Id属性为自增类型,其实EF默认会将Id属性设置为自增类型,但是在本例中,如果不显式声明,EF在生成数据库时会莫名其妙的将Id属性当作一般类型处理,不知道是不是因为最后一行设置RowVersion属性为Identity造成的。

我编写了一个小程序,用于显式控制EF根据类定义生成数据库,并且在生成数据库后,使用执行SQL语句的方式,修改数据库对象的定义,比如加入DEFAULT值或者添加索引等约束。下面是代码片段:

//DbContext构造器中的部分代码,通过isDoInitialize参数来控制是否初始化数据库。

public BestDbContext(string databaseName, bool isDoInitialize = true) : base(databaseName)

{if (!isDoInitialize)

{

Database.SetInitializer(null);

}

}//初始化数据库

Database.SetInitializer(new DropCreateDatabaseAlways());using (var db = new BestDbContext("name=" +databaseName))

{try{

db.Database.Initialize(force:false);

MessageBox.Show("Database initialized!");

}catch(Exception ex)

{

MessageBox.Show("Initialization Failed..." +ex.Message);

}stringsql;

sql= @"ALTER TABLE `kit`.`Stocks` CHANGE COLUMN `RowVersion` `RowVersion` DATETIME NOT NULL

DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ;";

db.Database.ExecuteSqlCommand(sql);

}

注意上面代码最后的sql执行部分,这里加入对RowVersion数据库服务器端的缺省值设置,自MySQL 5.6.5版本开始,DEFAULT CURRENT_TIMESTAMP 和 ON UPDATE CURRENT_TIMESTAMP 选项也可以应用到Datetime类型的列。

最后验证上述方法,使用 Entity Framework Profiler 试用版(http://hibernatingrhinos.com/products/EFProf),下载解压缩后,在Project引用中加入对HibernatingRhinos.Profiler.Appender.dll的引用,然后在应用的启动代码部分Application_Start in web applications,Program.Main in windows / console applications or the App constructor for WPF applications),加入这一行代码:HibernatingRhinos.Profiler.Appender.EntityFramework.EntityFrameworkProfiler.Initialize();

启动应用程序调试,并且启动EFProf.exe监控程序,你就可以随时看到EF动态生成的SQL命令了,很是方便,唯一的遗憾是这个工具是收费购买的,微软又没有提供非MSSQL的数据库EF的SQL监控工具。

这是Stocks表在插入新记录时,EF生成的SQL语句:

INSERT INTO`Stocks`

(`Quantity`,

`UpdatedBy`,

`UpdatedTime`,

`Location_Id`,

`Part_PartNo`,

`Batch_BatchNo`)VALUES ( 1,1,'2013-03-14T21:37:53' /*@gp1*/,1,'PART_A' /*@gp2*/,NULL);SELECT`Id`,

`RowVersion`FROM`Stocks`WHERE row_count() > 0

AND `Id` = last_insert_id()

可以看出,保存新对象实例到数据库时,EF会从数据库取回RowVersion的值,而这个值是数据库那边生成的。

这是更新Stocks表时,EF生成的SQL语句:

UPDATE`Stocks`SET `Quantity` = 6,

`UpdatedTime`= '2013-03-14T21:41:14' /*@gp1*/

WHERE (`Id` = 1)AND (`RowVersion` = '2013-03-14T21:14:25' /*@gp2*/)

可以看出,在更新对象实例到数据库时,EF会从使用先前从数据库取回RowVersion的值和主键作为条件来更新数据行,从而实现乐观并发控制。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/355732.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python元组操作_Python:元组操作总结

Python的元组和列表类似,不同之处在于元组中的元素不能修改(因此元组又称为只读列表),且元组使用小括号而列表使用中括号,如下: 1 tup1(physics,chemistry,1997,2000)2 tup2(1,2,3,4,5,6) 特别注意: 1、元组中只包含一个元素时,需…

Java函数式编程:Javaslang入门

Java是一门古老的语言,并且有很多新手在Java(JVM)领域挑战它们。 但是Java 8到来并带来了一些有趣的功能。 这些有趣的功能使编写新的惊人框架(如Spark Web框架或Javaslang)成为可能 。 在本文中,我们将介…

mysql语句表名大小写敏感_Mysql 表名大小写敏感

默认情况下,mysql在创建数据库对象时,是区分大小写的。故与microsoft之间进行移植时,要特别注意是否存在问题。在mysql中大小写与参数lower_case_table_names有很大关系。以下为官方解释:If set to 0, table names are stored as …

python json是什么_python json详解

在写某狗屁不通文章生成器的时候,发现有个json类型的文件看不懂。 于是先来搞懂什么是json json是一种储存数据的文件类型。 说人话,就是一种文件,能够数据 类似于DOC,excel 之类的。 json能储存半结构化数据。 简单来说&#xff…

mobx中跟新了数据视图没变化_【第1781期】MobX 简明教程

前言SEEConf,2020年1月4号杭州见,C位抢票见文章末尾。今日早读文章由腾讯whinc投稿分享。正文从这开始~~导读:MobX 是一个优秀的响应式状态管理库,在流行的状态管理库 Redux 之外为我们提供了其他选择。如果…

excel导航窗格_Excel小技巧16:在每天的某个时刻自动打开特定工作簿

学习Excel技术,关注微信公众号:excelperfect我想要在每天下班前,将自已一天的工作进行整理并简短记录在一个Excel工作簿中。然而,有时候忙,可能会忘记;有时候到下班时间了,急于下班,…

pdf secured_使您的Spring Security @Secured注释更干燥

pdf secured最近,Grails用户邮件列表中的一个用户想知道在定义Secured注释时如何减少重复 。 在Java批注中指定属性的规则非常严格,因此我看不到直接执行他所要求的方法的方法。 使用Groovy并没有真正的帮助,因为Groovy类中的注释大部分与Ja…

51单片机按键控制数码管0~9_51单片机外部中断

前面为大家介绍的点亮LED灯、数码管、按键只用到了51单片机的IO资源,我们要是仅仅用单片机点灯、操作数码管,那可真是大才小用了。这些都只是51单片机资源的冰山一角,51单片机还有好多的功能,我后面将为大家一一介绍。今天为大家介…

IIS7开启gZip动态压缩

1.安装动态压缩模块: 安装过程可能的报错:This application has requested the Runtime to terminate it in an unusual way. 解决办法>> 报错:错误: 尝试安装 动态内容压缩 失败,错误代码为 0x8007000E。 存储空间不足&am…

mysql查询不重复记录数_mysql查询不重复的行内容,不重复的记录数.count,distinct

有这么一个表 记录了id, p_id, p_name , p_content , p_time 1 343 aaa aaaaaa 2012-09-01 2 344 bbb bbbbbb 2012-09-02 3 321 ccc cccccccc 2012-09-03 4 343 aaa aaaaaa 2012-09-04 想查询不重复的行的内容,并且输出 p_sum ( 产品p_id出现重复的次数) sele有这么一个表记录了…

使用Java中的FileChannel和ByteBuffer在文件中读取/写入文件

过去,我讨论过RandomAccessFile以及如何将其用于在Java中进行更快的IO,在本Java NIO教程中,我们将了解如何通过使用FileChannel和ByteBuffer来使用读/写数据。 Channel提供了一种从文件读取数据的替代方法,它提供了比InputStream…

字符,字符串,int之间互相转换

字符转换成字符串:String str String.valueOf(ch); 字符转换成int: int a ch; 字符串转换成字符:char ch str.charAt(0); 字符串转换成Int:只包含数字的字符串可以通过Integer.parseInt(str)转换为int,但是包含字母…

mysql 导入百万级数据 几种 java_Java 修行第034天--执行计划及其使用--Oracle数据导入导出--第三章MySQL使用...

执行计划中牢记几句话:-- 尽量避免是*代替所有列,编写查询语句时使用具体列名代替*,可以防止全表扫描-- 尽可能少的使用like关键字进行模糊查询-- 建立适当的索引可以提高查询效率十三. 执行计划--通过PL/SQL Developer查看查询的1 执行计划是一条查询语句在Oracle中的执行过程…

10g添加用户 oracle_oracle 10g中如何创建用户

登录身份 说明sys/change_on_install SYSDBA或SYSOPER 不能以NORMAL登录,可作为默认的系统管理员system/manager SYSDBA或NORMAL 不能以SYSOPER登录,可作为默认的系统管理员sysman/oem_temp sysman 为oms的用户名scott/tiger NORMAL 普通用户aqadm /aqad…

摄像头分辨率怎么调整_亿联CAM50 - 智能话机专属高清摄像头

亿联CAM50是通过USB连接的高清视频摄像机,适用于亿联桌面高端智能话机(SIP-T58V和SIP-T58A),致力于提供一流的个人视频通信体验,优化视频协作。CAM50高清摄像机即插即用,无需额外安装驱动软件,也…

C orm mysql_Simple MySQL-C ORM

当你需要在纯C语言的应用程序中访问 MySQL 表中的数据时,是非常繁琐的事情,而该框架可以帮你大量的简化编码的工作,该框架采用 Python 开发,适用于 C 语言程序。示例代码:#include #include #include #include int mai…

jdbc:log4jdbc_使用Log4jdbc记录JDBC操作

jdbc:log4jdbc当我们开发任何应用程序,完成它或结束其任何模块时,我们都会开始优化过程。 大多数应用程序都包含数据库访问权限,如果您使用的是ORM ,则可能会使用hibernate 。 优化Hibernate持久层,要求准备阅读&#…

Mac 编译安装 Redis-3.2.3

Redis官方下载地址:http://redis.io/download Redis安装 cd /usr/local/src/redis-3.2.3 sudo make sudo make installcp ./src/redis-benchmark /usr/local/redis/redis-3.2 cp ./src/redis-check-aof /usr/local/redis/redis-3.2 cp ./src/redis-check-rdb /usr/l…

linux c mysql教程_linux下c操作mysql之增删改查

书接上文,继续进行linux 下c操作mysql。1.创建表/插入数据mysql> desc children-> ;----------------------------------------------------------| Field | Type| Null | Key | Default | Extra |----------------------------------------------------------| childno …

ios系统python编译器_MacBook如何安装Python编译器-百度经验

编程是一门需要动手实践的技能,由于Python的性能,许多人都将其作为学习编程的入门语言。而要想学好Python,首先要在电脑上安装Python,并安装一个可以解释Python的文本编辑器。在此以在MacBook上安装Sublime Text为例。 工具/原料 …