日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

EF 6 code first - 从SQL server迁移到MySQL

發布時間:2023/11/29 数据库 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 EF 6 code first - 从SQL server迁移到MySQL 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近鼓搗一個SaaS項目,后臺用的是entity framework 6 code first +SQL server,需要把數據庫遷移到MySQL,在這里記錄一下遇到的問題。時間比較久了記得不是很準確,供參考。

1, 以前殘留的Migration .cs文件(在項目的Migration目錄里,包括Configuration.cs)要統統刪除重新生成一遍,因為由SQL server connector生成的.cs文件與MySQL connector生成的.cs并不兼容。在nuget manager console里依次使用enable-migrations和add-migration <name>重新生成。

2,創建數據庫的時候報異常The ADO.NET provider with invariant name 'MySql.Data.MySqlClient' is either not registered in the machine or application config file, or could not be loaded. See the inner exception for details."(或者是一個別的異常?記得不是很清楚),一番度娘之后發現要在DbContext的子類上添加以下:

[DbConfigurationType(typeof(MySqlEFConfiguration))]

3,再次創建數據庫,又有異常Specified?key?was?too?long;?max?key?length?is?767 bytes,再一番度娘之后發現要在Configuration.cs文件里增加如下代碼:

SetSqlGenerator("MySql.Data.MySqlClient", new MySql.Data.Entity.MySqlMigrationSqlGenerator());

4,前進到建表的SQL語句,發現Procedure是MySQL的SQL語句的關鍵字,需要用`作為escape字符,而在SQL server里用的是[].

_helper.ExecuteCommand("INSERT INTO DBUpdateProcedure SET `Procedure` = @p0");

5,開始遷移stored procedure。SQL server創建stored procedure是在migration cs文件里手動調用this.CreateStoredProcedure()實現的,但是MySQL創建stored procedure有一個很特殊的語法,需要先將DELIMETER設為別的東西(比如“//”),再結束的時候再設回來。這個東西通過Migration cs文件沒法實現,即使通過this.SQL()方法也不行,EF貌似不能正確的理解DELIMETER語法。所以只能在別的地方創建一個MySQLScript對象,通過設定它的Delimeter屬性來達到同樣的效果。

sqlConn.Open();MySqlScript script_add_sp = new MySqlScript(sqlConn);StringBuilder sql = new StringBuilder();sql.Append(@"...");script_add_sp.Query = sql.ToString();script_add_sp.Delimiter = "//";script_add_sp.Execute();script_add_sp.Delimiter = ";";

?

6,stored procedure遷移好了,在調用的時候又報異常Only MySqlParameter objects may be stored。原因是有如下代碼:

var tenantIdParam = new SqlParameter("TenantId", tenantId);var officeIdParam = new SqlParameter("OfficeId", officeId);var searchTextParam = new SqlParameter("SearchText", searchText ?? "");var pageIndexParam = new SqlParameter("PageIndex", pageIndex);var pageSizeParam = new SqlParameter("PageSize", pageSize);var orderFieldParam = new SqlParameter("OrderField", orderField);var patients = DataContext.Database.SqlQuery<PatientPageResult>("csp_SearchPatient(@TenantId, @OfficeId, @SearchText, @PageIndex, @PageSize, @OrderField)",tenantIdParam, officeIdParam, searchTextParam, pageIndexParam, pageSizeParam, orderFieldParam).ToList();

這里我們必須構建MySqlParameter對象,而不是SQLParameter對象。并且MySql調用stored procedure要顯示的加CALL關鍵字,所以改正之后的代碼為:

var tenantIdParam = new MySqlParameter("TenantId", tenantId);var officeIdParam = new MySqlParameter("OfficeId", officeId);var searchTextParam = new MySqlParameter("SearchText", searchText ?? "");var pageIndexParam = new MySqlParameter("PageIndex", pageIndex);var pageSizeParam = new MySqlParameter("PageSize", pageSize);var orderFieldParam = new MySqlParameter("OrderField", orderField);var patients = DataContext.Database.SqlQuery<PatientPageResult>("CALL csp_SearchPatient(@TenantId, @OfficeId, @SearchText, @PageIndex, @PageSize, @OrderField)",tenantIdParam, officeIdParam, searchTextParam, pageIndexParam, pageSizeParam, orderFieldParam).ToList();

7,在Linq語句區數據轉化為對象的時候,報異常:System.FormatException occurred,?Message=String was not recognized as a valid Boolean.貌似因為實體類上有boolean屬性,MySQL connector生成的默認migration cs文件把這個屬性存在類型為tinyint的列里,但讀出來的時候又不知道怎么把0/1轉換為true/false,所以拋了這個異常。這個問題作為MySQL connector的一個bug報在了這里。就在快要絕望的時候,發現了stack overflow上牛人提的解決方案(原文),方法就是在modelbuilder里指定將boolean類型用bit列存儲,沒太明白,先記錄下來。

modelBuilder.Properties().Where(x => x.PropertyType == typeof(bool)).Configure(x => x.HasColumnType("bit"));

?

這只是個開始,后面的坑再開新的隨筆記錄。

?

轉載于:https://www.cnblogs.com/KennethYip/p/4747914.html

總結

以上是生活随笔為你收集整理的EF 6 code first - 从SQL server迁移到MySQL的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。