SQLServer数据库之无需修改实体和配置-在MySql中使用和SqlServer一致的并发控制
小标 2018-10-19 来源 : 阅读 1145 评论 0

摘要:本文主要向大家介绍了SQLServer数据库之无需修改实体和配置-在MySql中使用和SqlServer一致的并发控制,通过具体的内容向大家展现,希望对大家学习SQLServer数据库有所帮助。

本文主要向大家介绍了SQLServer数据库之无需修改实体和配置-在MySql中使用和SqlServer一致的并发控制,通过具体的内容向大家展现,希望对大家学习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();
            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().FirstOrDefault();
  customer1.PhoneNumber="t1";
  using (var db2 = GetContext())
  {
    var customer2 = db2.Set().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的价值在测试和隔离实现)

本文由职坐标整理并发布,希望对同学们学习SQL Server有所帮助,更多内容请关注职坐标数据库SQL Server数据库频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程