將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連接名")
        {
        }
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM