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`[email protected], `RowVersion`[email protected] 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的价值在测试和隔离实现)

时间: 2024-10-13 05:05:04

Entity Framework 6 Code First 系列:无需修改实体和配置-在MySql中使用和SqlServer一致的并发控制的相关文章

Entity Framework 6 Code First 系列:使SQLite.CodeFirst支持DropCreateDatabaseIfModelChanges和RowVersion

没什么好说的,能支持DropCreateDatabaseIfModelChanges和RowVersion的Sqlite谁都想要.EntityFramework7正在添加对Sqlite的支持,虽然EF7不知道猴年马月才能完成正式版,更不知道MySql等第三方提供程序会在什么时候跟进支持,但是EF7中的确出现了Sqlite的相关代码.Sqlite支持EF6的CodeFirst,只是不支持从实体生成数据库,估计有很多人因为这个原因放弃了使用它.现在SQLite.CodeFirst的简单实现可以让我们

1.Relationship in Entity Framework Using Code First Approach With Fluent API【使用EF Code-First方式和Fluent API来探讨EF中的关系】

In this article, you will learn about relationships in Entity Framework using the Code First Approach with Fluent API. 在这篇文章中,你将会学习到使用EF Code-First方式和Fluent API来探讨EF中的关系(一对一,一对多,多对多). Introduction[介绍] A relationship, in the context of databases, is a

ASP.NET MVC5.0+Entity Framework(EF)6.1系列教程

ASP.NET MVC5.0+Entity Framework(EF)6.1系列教程 从webform+ado.net开发模式转换到asp.net mvc+ef开发模式已经有一年多时间了.一直希望能够将自己开发中的一点微薄经验写下啦,现在列个目录,鼓励自己写下去. 1.1 Entity Framework(EF) ASP.NET MVC+Entity Framework(EF)技术介绍 ASP.NET MVC+Entity Framework(EF)项目搭建 3种Entity Framework

创建ASP.NET Core MVC应用程序(3)-基于Entity Framework Core(Code First)创建MySQL数据库表

创建ASP.NET Core MVC应用程序(3)-基于Entity Framework Core(Code First)创建MySQL数据库表 创建数据模型类(POCO类) 在Models文件夹下添加一个User类: namespace MyFirstApp.Models { public class User { public int ID { get; set; } public string Name { get; set; } public string Email { get; se

MVC2、MVC3、MVC4、MVC5之间的区别 以及Entity Framework 6 Code First using MVC 5官方介绍教程

现在MVC的技术日趋成熟,面对着不同版本的MVC大家不免有所迷惑 -- 它们之间有什么不同呢?下面我把我搜集的信息汇总一下,以便大家能更好的认识不同版本MVC的功能,也便于自己查阅. View Engine : View Engine is responsible for rendering of the HTML code from your views to the browser.MVC 2 uses only Web Forms view engine (.aspx) as a defa

Entity Framework 6 Code First 实践系列(1):实体类配置总结

EF实体类的配置可以使用 数据注释或 Fluent API两种方式配置,Fluent API 配置的关键在于搞清实体类的依赖关系,按此方法配置,快速高效合理.为了方便理解,我们使用简化的实体A和B以及A.B的配置类AMap和BMap,来演示如何正确配置实体类关系的过程. public class A { public int Id { get; set; } } public class B { public int Id { get; set; } } public class AMap :

【转】Entity Framework 6 Code First 实践系列(1):实体类配置-根据依赖配置关系和关联

本文转自:http://www.cnblogs.com/easygame/p/3622893.html EF实体类的配置可以使用数据注释或Fluent API两种方式配置,Fluent API配置的关键在于搞清实体类的依赖关系,按此方法配置,快速高效合理.为了方便理解,我们使用简化的实体A和B以及A.B的配置类AMap和BMap,来演示如何正确配置实体类关系的过程. public class A { public int Id { get; set; } } public class B { p

Entity Framework mvc Code First data migration

1. Code First 可以先在代码里写好数据模型,自动生成DB.下一次启动的时候会根据__MigrationHistory判断 数据库是否和模型一致. 详情参考:http://blogs.msdn.com/b/adonet/archive/2012/02/09/ef-4-3-code-based-migrations-walkthrough.aspx 如果想改变数据库的某个字段,而又不想重新生成一遍数据库的话.请按照以下操作做: Package Manager console: enabl

使用Entity Framework Core Code First创建SQLite数据库

Entity Framework Core(以下简称"EF Core")支持多种数据库.在这篇文章中,我们看看如何使用EF Core的Code First方式创建SQLite数据库 下载SQLite,解压后会得到三个文件,放到c:\sqlite目录下 我们先创建一个.NET Core控制台程序 添加EF Core for SQLite组件库 "dependencies": { "Microsoft.EntityFrameworkCore.Sqlite&qu