簡介
項目使用MSSql作為數據庫,但是因為SQL服務器貴那么一點,並發連接差那么一點,要把數據遷移到MySQL,順帶遷移過程以及問題。
環境
· Visual Studio 2013
· MySQL 5.7
· Entity Framework 6.1.3
正文
遷移過程
1. 安裝MySQL,順帶安裝 MySQL for Visual Studio、MySQL Connector Net
2. 在Entity Framework 項目和 WebSite項目中添加Nuget包,MySql.Data.Entity,我這里添加的是6.9.6版本,添加時后會把MySQL.Data作為依賴項加入到項目中,完成后可以看到web.config和app.config下增加了MySQL的 provider和DbProvideFactories。
<entityFramework> <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework"> <parameters> <parameter value="v11.0" /> </parameters> </defaultConnectionFactory> <providers> <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /> <provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6, Version=6.9.9.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d"></provider> </providers> </entityFramework>
<system.data> <DbProviderFactories> <remove invariant="MySql.Data.MySqlClient" /> <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.9.9.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" /> </DbProviderFactories> </system.data>
3. 修改Web.config的連接字符串,providerName修改成:MySql.Data.MySqlClient。
<add name="DefaultConnection" providerName="MySql.Data.MySqlClient" connectionString="Data Source=127.0.0.1;Initial Catalog=Demo;User ID=root;Password=root" />
4. 回到EntityFramework項目中,找到DbContext類,為類添加屬性:[DbConfigurationType(typeof(MySql.Data.Entity.MySqlEFConfiguration))]
[DbConfigurationType(typeof(MySql.Data.Entity.MySqlEFConfiguration))] public class MyDbContext : DbContext { /// <summary> /// 設置數據實體對應的數據庫連接 /// </summary> public MyDbContext() : base("DefaultConnection") { } //用Fluent api必須重寫OnModelCreating方法 protected override void OnModelCreating(DbModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();//移除復數表名的契約 } }
5. OK,這些工作做完,基本就可以了,打開程序包管理器控制台,虔誠祈禱,然后輸入:update-database
遷移過程問題
1. 未將對象引用設置到對象的實例。
問題描述:這是一個比較通用的錯誤提示,很多Error都會提示這個,網上找了一些不太對,最后發現是因為啟動項設置為EF項目,同時默認項目也是EF項目,因為在config文件中不到連接字符串導致的。
解決方案:在EF的app.config中添加連接串,或者啟動項目設置為WebSite。
2. underlying provider does not support the type 'nvarchar(max)'.
問題描述:字面意思就是說,provider不支持類型”nvarchar(max)”,這與MySQL數據庫支持的數據類型有關系。
解決方案:找一下Entity定義中是不是有string類型,添加 屬性如: [StringLength(1000)],然后問題解決。
3. 提供程序未返回 ProviderManifestToken 字符串。
問題原因:連接字符串寫錯了 。
正確寫法:data source不能用.代替
<add name="DefaultConnection" providerName="MySql.Data.MySqlClient" connectionString="Data Source=127.0.0.1;Initial Catalog=demo;User ID=root;Password=root" />
4. 未解析成員“MySql.Data.MySqlClient.MySqlException,MySql.Data, Version=6.9.9.0, Culture=neutral, PublicKeyT
System.Runtime.Serialization.SerializationException:
未解析成員“MySql.Data.MySqlClient.MySqlException,MySql.Data, Version=6.9.9.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d”的類型。 在 System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate) 在 System.Data.Entity.Migrations.Design.ToolingFacade.Run(BaseRunner runner) 在 System.Data.Entity.Migrations.Design.ToolingFacade.Update(String targetMigration, Boolean force) 在 System.Data.Entity.Migrations.UpdateDatabaseCommand.<>c__DisplayClass2.<.ctor>b__0() 在 System.Data.Entity.Migrations.MigrationsDomainCommand.Execute(Action command)
未解析成員“MySql.Data.MySqlClient.MySqlException,MySql.Data, Version=6.9.9.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d”的類型。
解決方案:一般發生在從原來開發環境換到新的開發環境,在開發環境中缺少“mysql-connector-net”這個東西 ,下載安裝即可。
5. 從索引 0 處開始,初始化字符串的格式不符合規范。
問題描述:這個問題和第一個差不多,只不過換了個提示方式,因為我在項目中有沒有將包含連接字符串的項目設置為啟動項,導致webconfig中缺少連接字符串導致的。
PM> update-database 指定“-Verbose”標志以查看應用於目標數據庫的 SQL 語句。 System.ArgumentException: 從索引 0 處開始,初始化字符串的格式不符合規范。 在 System.Data.Common.DbConnectionOptions.GetKeyValuePair(String connectionString, Int32 currentPosition, StringBuilder buffer, Boolean useOdbcRules, String& keyname, String& keyvalue) 在 System.Data.Common.DbConnectionOptions.ParseInternal(Hashtable parsetable, String connectionString, Boolean buildChain, Hashtable synonyms, Boolean firstKey) 在 System.Data.Common.DbConnectionOptions..ctor(String connectionString, Hashtable synonyms, Boolean useOdbcRules) 在 System.Data.Common.DbConnectionStringBuilder.set_ConnectionString(String value) 在 MySql.Data.MySqlClient.MySqlConnectionStringBuilder..ctor(String connStr) 在 MySql.Data.MySqlClient.MySqlConnection.set_ConnectionString(String value) 在 MySql.Data.MySqlClient.MySqlConnection..ctor(String connectionString) 在 MySql.Data.Entity.MySqlConnectionFactory.CreateConnection(String connectionString) 在 System.Data.Entity.Internal.LazyInternalConnection.Initialize() 在 System.Data.Entity.Internal.LazyInternalConnection.get_Connection() 在 System.Data.Entity.Internal.LazyInternalContext.get_Connection() 在 System.Data.Entity.Infrastructure.DbContextInfo..ctor(Type contextType, DbProviderInfo modelProviderInfo, AppConfig config, DbConnectionInfo connectionInfo, Func`1 resolver) 在 System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration configuration, DbContext usersContext, DatabaseExistenceState existenceState, Boolean calledByCreateDatabase) 在 System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration configuration) 在 System.Data.Entity.Migrations.Design.ToolingFacade.BaseRunner.GetMigrator() 在 System.Data.Entity.Migrations.Design.ToolingFacade.UpdateRunner.Run() 在 System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate) 在 System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate) 在 System.Data.Entity.Migrations.Design.ToolingFacade.Run(BaseRunner runner) 在 System.Data.Entity.Migrations.Design.ToolingFacade.Update(String targetMigration, Boolean force) 在 System.Data.Entity.Migrations.UpdateDatabaseCommand.<>c__DisplayClass2.<.ctor>b__0() 在 System.Data.Entity.Migrations.MigrationsDomainCommand.Execute(Action command) 從索引 0 處開始,初始化字符串的格式不符合規范。
解決方案:將包含連接字符串的項目設置為啟動項目,將包含dbContext的項目設置為默認遷移項目,就是程序包管理控制台中的默認項目。