在最近的項目中,打算使用EntityFramework與MySql資料庫來配合,不想卻出現了一些無可奈何的問題。 開發環境如下:
EntityFramework 版本:4.3.1
.Net Framework 版本:4.0
MySql 版本:5.5
Connector/Net 版本:6.5.4
示範代碼比較簡單,建立一個控制台應用項目:
public class Post
{
public int Id { get; set; }
public string Title { get; set; }
public string Content { get; set; }
}
public class Blog : DbContext
{
public IDbSet<Post> Posts { get; set; }
}
static void Main(string[] args)
{
using (var blog = new Blog())
{
var post = new Post()
{
Title = "Test Title",
Content = "This is my content for test"
};
blog.Posts.Add(post);
blog.SaveChanges();
}
}
app.config的配置是這樣
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<connectionStrings>
<add name="Blog" connectionString="server=localhost;User Id=root;Pwd=password;Persist Security Info=True;database=Blog" providerName="MySql.Data.MySqlClient" />
</connectionStrings>
</configuration>
原本在SqlServer下是能正常執行的,但是換作MySql之後,在首次運行時,會拋出一個異常,內容如下:
Exception: MySql.Data.MySqlClient.MySqlException: You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server version for the right syntax to use near
'NOT NULL,
`ProductVersion` mediumtext NOT NULL);
ALTER TABLE `HistoryRow` ' at line 6
從內容上猜測,是與EF4.3.1的新特性有關的問題,新版本增加了一個CodeFirst Migrations功能,在初始化資料庫的過程中會建立一張MigrationHistory表到資料庫中,於是我嘗試捕捉相關的sql指令碼,具體如下:
CREATE TABLE `__MigrationHistory`(
`MigrationId` mediumtext NOT NULL,
`CreatedOn` datetime NOT NULL,
`Model` varbinary NOT NULL,
`ProductVersion` mediumtext NOT NULL);
這段指令碼放置在MySql命令列去執行,也是相同的異常資訊。仔細查看錯誤提示,發現varbinary這個類型出了問題,在MySql中居然不能正確識別,反而修改成varbinary(1)才可以通過,也就是要求此類型必須要給定長度。可是,這明顯是EF自動產生的,無從修改啊。 因此查看MSDN的官方文檔,找到有關CodeFirst Migrations的配置類,如果不需要自動產生的話,是可以通過配置類DbMigrationsConfiguration的AutomaticMigrationsEnabled屬性來設定禁用的,我按協助上的樣本寫了相關的代碼繼承了此類,可惜仍然沒有效果,可能是哪裡沒有設定正確。當然,我想更多情況應該還是期望使用這個Migration功能的,只是不知道EF是否提供介面,由開發人員自己去實現自動產生指令碼?暫時未找到答案。所以,為了能順利使用CodeFirst和MySql的組合,只好避開這個問題,將EF版本降到4.1.10715,然後一切都可以正常運行了。