zoukankan      html  css  js  c++  java
  • 将SQL SERVER数据库改成MySql

     (www.helpqy.com) 架构在阿里云上,最先想采用SQL SERVER,想大家都是微软家族的嘛。但是发现SQL SERVER需要的配置比较高,需要的银子也比较多,最后在纠结之下换成了MySql。由于整个网站基于微软的asp.net MVC架构,同时基于EF6.0,而MVC架构默认采用了SQL SERVER,这里又与code first混合在一起,所以在修改和过渡过程中还是遇到了不少问题。这个过程中参考了博客园不少前辈的文章,真是太感谢了。其中主要参考的一篇外文是:“ASP.NET Identity: Using MySQL Storage with an EntityFramework MySQL Provider (C#)”。时间太长了,现在在总结和回忆,可能还是会遗漏掉一些细节,请各位,也请我自己谅解哈,嘿嘿。

    1. 通过NuGet下载Mysql的provider,以便EF能够连接Mysql数据库。下载MySql.Data.Entity包时,会有两个包被集成进工程,如下所示:

    2. 然后是Web.config的修改。

        在connectionStrings中去掉SQL SERVER相关的连接字符串,加入mysql的连接字符串,如下所示:

    1 <connectionStrings>   
    2     <add name="ConnectionName" 
    3          providerName="MySql.Data.MySqlClient"    
    connectionString
    ="Server=xxx.xxx.xxx.xxx;Uid=xxx;Pwd=xxx;Database=xxxxx" /> 4 </connectionStrings>

        在providers中加入mysql的provider信息:

    <providers>
          <provider invariantName="MySql.Data.MySqlClient" 
    type
    ="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6" /> </providers>

        在system.data中加入mysql的factory信息:

    <system.data>
        <DbProviderFactories>
             <remove invariant="MySql.Data.MySqlClient"></remove>
             <add name="MySQL Data Provider" 
               invariant="MySql.Data.MySqlClient"
               description=".Net Framework Data Provider for MySQL"
               type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.8.3.0, Culture=neutral, PublicKeyToken=xxxx" />
        </DbProviderFactories>
    </system.data>

    3. 加入定制化的MigrationHistory context。这一节非常重要,重点参考了上述的那篇美文。

        EF的Code First采用Migration History表来保证model和数据库的一致性。但是数据库换成Mysql后默认的主键长度超过了Mysql最大允许的767字节,所以必须修改主键长度,这里需要修改HistoryContext,可以新增加一个类来继承HistoryContext,如下所示:

     1 public class MySqlHistoryContext : HistoryContext
     2     {
     3         public MySqlHistoryContext(
     4             DbConnection existingConnection,
     5             string defaultSchema)
     6             : base(existingConnection, defaultSchema)
     7         { }
     8 
     9         protected override void OnModelCreating(DbModelBuilder modelBuilder)
    10         {
    11             base.OnModelCreating(modelBuilder);
    12             modelBuilder.Entity<HistoryRow>().Property(h => h.MigrationId).HasMaxLength(100).IsRequired();
    13             modelBuilder.Entity<HistoryRow>().Property(h => h.ContextKey).HasMaxLength(200).IsRequired();
    14         }
    15     }

        为了让EF使用修改后的HistoryContext,而不使用默认的HistoryContext,则需要增加类修改DbConfiguration:

    1 public class MySqlConfiguration : DbConfiguration
    2     {
    3         public MySqlConfiguration()
    4         {
    5             SetHistoryContext("MySql.Data.MySqlClient", (conn, schema) => new MySqlHistoryContext(conn, schema));
    6         }
    7     }

    4. MySql provider无法直接支持EF的migration和code first,需要增加一个定制化的EF initializer:

     1 public class MySqlInitializer : IDatabaseInitializer<ApplicationDbContext>
     2     {
     3         public void InitializeDatabase(ApplicationDbContext context)
     4         {
     5             if (!context.Database.Exists())
     6             {
     7                 context.Database.Create();
     8             }
     9             else
    10             {
    11                 var migrationHistoryTableExists = ((IObjectContextAdapter)context).ObjectContext.ExecuteStoreQuery<int>(
    12                     string.Format(
    13                     "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = '{0}' AND table_name = '__MigrationHistory'",
    14                     "XXX数据库名"
    15                     ));
    16 
    17                 if (migrationHistoryTableExists.FirstOrDefault() == 0)
    18                 {
    19                     context.Database.Delete();
    20                     context.Database.Create();
    21                 }
    22             }
    23         }
    24     }

        同时需要在DbContext中使用此定制化的initializer:

    public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
        {
            static ApplicationDbContext()
            {
                Database.SetInitializer(new MySqlInitializer());
            }
    
            public virtual DbSet<xxxx> xxxx { get; set; }
            public ApplicationDbContext()
                : base("xxxx连接名")
            {
            }
        }
  • 相关阅读:
    动态规划
    Python第二天学习
    Python第一天学习---基础语法
    java易错知识点
    C语言---指针复习
    排序汇总
    课程设计---创建族谱管理系统
    Vue第五篇 Vue的生命周期
    Vue第四篇 Vue路由系统
    Vue第三篇 Vue组件
  • 原文地址:https://www.cnblogs.com/HelpQY/p/3873438.html
Copyright © 2011-2022 走看看