Entity Framework 6 Code First 系列:无需修改实体和配置-在MySql中使用和SqlServer一致的并发控制
无需修改实体和配置,在MySql中使用和SqlServer一致的并发控制。修改RowVersion类型不可取,修改为Timestamp更不可行。Sql Server的RowVersion生成一串唯一的二进制保证Row的版本,无关TimeStamp,更无论TimeStamp的精度问题。使用MySql触发器只能解决uuid的插入的默认值和更新的随机值,由于MySql的自身为了防止无限递归的策略,它的触发器无法在当前表的触发器中更新当前表,所以触发器无法实现更新在SqlServer中由数据库生成的RowVersion字段的值。所以MySql中的RowVersion只能由应用程序赋值。
在EF中采用IsConcurrencyToken配置后RowVersion即自动用于where子句中用于比较Row Version,通过重写SaveChanges方法在每次添加和更新时设置RowVersion的值即可实现在更新时同时比较Row Version的当前版本和更新Row Version的目的,同时可以正确的取回更新后的Row Version值。
1.定义并发控制字段
public interface IRowVersion
{
byte[] RowVersion { get; set; }
}
2.配置并发控制字段
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Configurations.AddFromAssembly(typeof(MySqlDbContext).Assembly);
modelBuilder.Properties().Where(o => typeof(IRowVersion).IsAssignableFrom(o.DeclaringType)&&o.PropertyType==typeof(byte[])&&o.Name=="RowVersion")
.Configure(o => o.IsConcurrencyToken().HasDatabaseGeneratedOption(DatabaseGeneratedOption.None));
Database.SetInitializer(new MySqlDbInitializer());
}
3.手动对RowVersion赋值
public override int SaveChanges()
{
this.ChangeTracker.DetectChanges();
var objectContext = ((IObjectContextAdapter)this).ObjectContext;
foreach (ObjectStateEntry entry in objectContext.ObjectStateManager.GetObjectStateEntries(EntityState.Modified | EntityState.Added))
{
var v = entry.Entity as IRowVersion;
if (v != null)
{
v.RowVersion = System.Text.Encoding.UTF8.GetBytes(Guid.NewGuid().ToString());
}
}
return base.SaveChanges();
}
4.检查生成的Sql语句
UPDATE `Customer` SET `PhoneNumber`=@gp1, `RowVersion`=@gp2 WHERE (`Id` = 1) AND (`RowVersion` = @gp3) -- @gp1: '635655975120384389' (Type = String, IsNullable = false, Size = 18) -- @gp2: 'System.Byte[]' (Type = Object, IsNullable = false, Size = 36) -- @gp3: 'System.Byte[]' (Type = Object, IsNullable = false, Size = 36)
5.查看数据中的RowVersion
6.准备测试代码
public static void Test()
{
var db1 = GetContext();
var customer1 = db1.Set<Customer>().FirstOrDefault();
customer1.PhoneNumber="t1";
using (var db2 = GetContext())
{
var customer2 = db2.Set<Customer>().FirstOrDefault();
customer2.PhoneNumber = "t2";
db2.SaveChanges();
}
db1.SaveChanges();
}
7.查看测试结果:
总结:
1.需要唯一版本号的生成支持,Sql Server(Compact)本身支持,MySql的uuid函数也支持。
2.需要设置Insert时的RowVersion默认值和更新RowVersion版本号,Sql Server(Compact)本身支持,MySql只支持不能用于RowVersion的TimeStamp的默认值和自动更新。因此在MySql中只能在应用中设置Row Version。
不存在的缺点:
1.ASP.NET慢(没设置好IIS的Application Initialization和回收配置等选项)
2.Entity Framework慢(没有设置per request one DbContext和Generate Views)
3.Entity Framework加载数据太多(不正确使用AutoMapper和延迟加载)
4.Entity Framework不需要IRepository(IRepository的价值在测试和隔离实现)
Entity Framework 6 Code First 系列:无需修改实体和配置-在MySql中使用和SqlServer一致的并发控制的更多相关文章
- Entity Framework 6 Code First系列1: 实体类1:1配置
从4.1版本开始,EF开始支持Code First模式,值得注意的是Code First不是和DataBase First或Model First平级的概念,而是和EDM平级的概念.使用Code Fi ...
- Entity Framework 6.0 入门系列 第一篇
Entity Framework 6.0 入门系列 第一篇 好几年前接触过一些ef感觉不是很好用,废弃.但是 Entity Framework 6.0是经过几个版本优化过的产物,性能和功能不断完善,开 ...
- EF(Entity Framework)系统学习系列
好久没写博客了,继续开启霸屏模式,好了,废话不多说,这次准备重新系统学一下EF,一个偶然的机会找到了一个学习EF的网站(http://www.entityframeworktutorial.net/) ...
- Entity Framework 6 Code First新特性:支持存储过程
Entity Framework 6提供支持存储过程的新特性,本文具体演示Entity Framework 6 Code First的存储过程操作. Code First的插入/修改/删除存储过程 默 ...
- AppBox升级进行时 - 拥抱Entity Framework的Code First开发模式
AppBox 是基于 FineUI 的通用权限管理框架,包括用户管理.职称管理.部门管理.角色管理.角色权限管理等模块. 从Subsonic到Entity Framework Subsonic最早发布 ...
- Entity Framework 之 Code First
使用NuGet助您玩转代码生成数据————Entity Framework 之 Code First [前言] 如果是Code First老鸟或者对Entity Framework不感兴趣,就不用浪费 ...
- Entity Framework 6 Code First的简单使用和更新数据库结构
一.安装Entity Framework 6 在项目中右击选择“管理NuGet程序包",联机搜索Entity Framework,点击安装 二.配置数据库连接 在App.config中加入数 ...
- 【极力分享】[C#/.NET]Entity Framework(EF) Code First 多对多关系的实体增,删,改,查操作全程详细示例【转载自https://segmentfault.com/a/1190000004152660】
[C#/.NET]Entity Framework(EF) Code First 多对多关系的实体增,删,改,查操作全程详细示例 本文我们来学习一下在Entity Framework中使用Cont ...
- 创建ASP.NET Core MVC应用程序(3)-基于Entity Framework Core(Code First)创建MySQL数据库表
创建ASP.NET Core MVC应用程序(3)-基于Entity Framework Core(Code First)创建MySQL数据库表 创建数据模型类(POCO类) 在Models文件夹下添 ...
随机推荐
- <2014 04 16> 上班实习第一天
找了家开发3D printer的创业公司实习,做(嵌入式)软件工程师.今天第一天. 1.熟悉了基于SLA技术的3D打印机的主要关键问题,机械结构. 控制系统是基于PC-Clinet和一个树莓派ARM/ ...
- elastic search使用
elastic使用 使用python时注意保持一个好习惯:不要使用类似str.type这样的变量名,很容易引发错误: https://blog.csdn.net/lifelegendc/article ...
- .net ASPxTreeList 使用手记
ASPxTreeList在使用ASPxGridViewExporter控件做导出时,如果指定文件名是中文时会乱码可以用以下方法解决: grvExporter为ASPxGridViewExporter控 ...
- Android项目使用Ant多渠道打包(最新sdk)
参考文章: http://blog.csdn.net/liuhe688/article/details/6679879 http://www.eoeandroid.com/thread-323111- ...
- ViewConfiguration 和 ViewConfigurationCompat
Contains methods to standard constants used in the UI for timeouts, sizes, and distances. 一.几个常用的方法 ...
- Leetcode 之 Keys Keyboard
1. 2 Keys Keyboard 先把dp的最小不走都设置为无穷大(Integer.MAX_VALUE),初始化条件:dp[0] = dp[1] = 0,状态转移方程为dp[i] = Math.m ...
- 关于c#继承
如下代码所示:最后输出的是:8,3,7,4 public class A { public virtual void One(int i) { Console.Write(i); } public v ...
- sql查询原理和Select执行顺序
一 sql语句的执行步骤 1)语法分析,分析语句的语法是否符合规范,衡量语句中各表达式的意义. 2) 语义分析,检查语句中涉及的所有数据库对象是否存在,且用户有相应的权限. 3)视图转换,将涉及视图的 ...
- 重置Linux普通账号和root账号密码
今天想在Linux测试下HTTPie, 突然发现虚拟机里面的Linux, root账号和普通账号密码都忘记了. 百度了半天发现答案都不对, 最后用Google搜到了答案. 本人系统环境: VMware ...
- Python一些常用模块
阅读目录 一: collections模块 二: time,datetime模块 三: random模块 四: os模块 五: sys模块 六: json,pickle 七: re正则模块 八:re模 ...