【親測】Asp.net Mvc5 + EF6 code first 方式鏈接MySQL總結

本文原文地址爲:https://www.cnblogs.com/summit7ca/p/5423637.htmlhtml

原文測試環境爲windows 8.1+Vs2013+MySql5.7.12mysql

本人在win10+vs2017+MySql5.7下測試經過web


最近因爲服務器變動爲Linux系統.MsSql for Linux何時出來到生產環境使用仍是要很長時間的.因而考慮使用Mysql數據庫,ORM使用EF.因而先踩下坑順便記錄一下,有須要的tx能夠參考下.sql

當你考慮使用EF鏈接Mysql的時候確定是已經在網上搜了一堆教程.網上教程基本都是使用控制檯作演示.跟着一步步來姿式沒錯的話可能會正常運行,但項目中使用分層後,把數據層剝離出去,再使用code first鏈接瞬間蒙B了,各類奇葩問題隨之而來.咋跟教程說的不同呢...因此本文就一步步的介紹如何在分層的項目中使用EF code first鏈接Mysql.
ps:本文測試環境爲windows 8.1+Vs2013+MySql5.7.12數據庫

一.搭建環境及安裝對應組件

首先建立一個空的MVC項目後簡單的再建立一個類庫項目用於EF的操做以及實體的存放(這裏爲了演示沒有建立過多的項目).最終結果以下:windows

 

而後在.Data項目中用Nuget安裝EF.而後安裝MySql數據驅動所需dll:服務器

MySQL.Data.Entities.dll  //Nuget默認會帶上MySQL.Data.dll

本人是在Data項目中,先安裝最新版的EntityFramework(版本號:6.2)網絡

而後再安裝:MySql.Data.Entity.EF6(安裝後的名稱爲MySql.Data.Entity.EF6,此項會自動安裝MySql.Data)app

在啓動項目中沒有安裝這兩項,也是經過了測試的ide

添加一個繼承自DBContext的類MyDbContext.cs:

namespace EF2MySqlApp.Data
{
    public class MyDbContext:DbContext
    {
        public MyDbContext()
        {
 
        }
 
        public DbSet<BookInfo> BookInfoes { get; set; }
    }
}

此處,本人修改成

public class MyDbContext : DbContext
    {
        public MyDbContext():base("name=MyDbContext")
        {

        }
        protected override void OnModelCreating(DbModelBuilder mb)
        {
            base.OnModelCreating(mb);
        }
        public DbSet<BookInfo> BookInfoes { get; set; }
    }

 

接着建個文件夾放實體類BookInfo.cs:

namespace EF2MySqlApp.Data
{
    public class BookInfo
    {
        public int Id { get; set; }
 
        public string Number { get; set; }
 
        public string Name { get; set; }
 
        public string Author { get; set; }
 
        public decimal Price { get; set; }
 
        public bool Deleted { get; set; }
 
        public DateTime CreatedOn { get; set; }
    }
}

結構相似這樣:

  

二.配置EF

接着該是配置數據庫鏈接字符串了,如今在App.Config下添加connectionString字節,注意別寫到configSections上邊去了,不然進行添加Migration會報節點配置錯誤.

本人是將此內容加到啓動項目的web.config中的。

<connectionStrings>
  <add name="MyDbContext" connectionString="Data Source=localhost;port=3306;Initial Catalog=myappdb;uid=root;password=123456;Charset=utf8" providerName="MySql.Data.MySqlClient" />
</connectionStrings>

而後打開程序包管理器控制檯(-_-不知道的請自定搜索),默認項目選擇.Data項目,而後輸入這個命令:

Enable-Migrations  //啓用遷移

 本人測試中,此部會報」未將對象引用設置到對象的實例「的錯誤:

不用管它,接着下一步

沒有錯誤提示接着輸入:

Add-Migration record1  //給本次遷移記錄起個名字 這個名字能夠隨便起,儘可能別重名 注意這裏的Migration沒有s結尾.

這時看到項目下已經多了幾個文件:
Configuration.cs爲進行遷移前的配置文件.以時間戳+剛纔輸入的名字的文件爲遷移記錄文件.本文重點不在此,因此各個做用在此不作過多介紹.有興趣可自行搜索學習.
在Configuration類的構造函數中有這麼一句話,它的做用在因而否啓用自動遷移,默認不啓用:

AutomaticMigrationsEnabled=false;

在Seed方法中能夠添加種子數據,遷移成功後將會執行這個方法,把數據插入到數據庫中.

protected override void Seed(EF2MySqlApp.Data.MyDbContext context)
{
     context.BookInfoes.AddOrUpdate(x => x.Id,
         new BookInfo { Name="C#大法好",Author="summit", Number="1234",Price=1024}
      );
     context.SaveChanges();
}

注意最後須要保存一下  

這個時候若是直接update-database將會報Sql Server鏈接失敗的錯誤:以下:

在與 SQL Server 創建鏈接時出現與網絡相關的或特定於實例的錯誤。未找到或沒法訪問服務器。....

問題來了,想鏈接MySql怎麼默認使用了Sql Server呢.這是EF默認鏈接的是SqlServer 因此要告訴EF咱們須要使用Mysql:

在Configuration類的構造函數中加入:

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

給MyDbcontext類增長DbConfigurationType特性:

[DbConfigurationType(typeof(MySql.Data.Entity.MySqlEFConfiguration))]
    public class MyDbContext:DbContext
    {
        public MyDbContext()
        {
 
        }
 
        public DbSet<BookInfo> BookInfoes { get; set; }
    }

  ps:這個也能夠在config文件裏配置,我的比較喜歡用代碼控制.

再次運行Update-Database -v 依然報錯,但提示字符串格式不正確,往上翻翻看到DbContenniton獲取字符串的時候出錯了,因而猜想是不是鏈接字符串的問題:

System.ArgumentException: 從索引 0 處開始,初始化字符串的格式不符合規範。
在 System.Data.Common.DbConnectionOptions.GetKeyValuePair(String connectionString, Int32 currentPosition, StringBuilder buffer, Boolean useOdbcRules, String& keyname, String& keyvalue) 

 此處,由於本人將扎鏈接字符串寫到啓動項目的web.config的緣由,測試時未報錯。

鏈接字符串測試沒發現問題,那會不會是找不到這個鏈接字符串呢? N久後發如今這個控制檯中使用的config文件默認是到當前啓動項目下尋找config文件.

把Data項目設爲啓動項後再次運行報: 

The underlying provider does not support the type 'nvarchar(max)'.

這個錯誤因爲MySql字段不兼容string類型,在string類型字段前加註解[MaxLength(100)]便可解決(奇怪的是我用vs2015測試是不會報這個錯誤的..).

此處,本人測試時未報錯。多是VS2017有所改進的緣由。所以,並未在string類型字段前加註解[MaxLength(100)]。

 

再次執行Update-DataBase -v 成功!
若是使用的mysql命令行:輸入這些命令查看是否建立成功:

show databases;
use myappdb;
select * from bookinfoes;

用其餘客戶端的那就更沒必要多說了. 

另可能出現的錯誤問題:

Error A.出現這個錯誤請先檢查鏈接字符串是否正確,mysql與mssql的鏈接字符串有所區別.確認無誤後檢查此鏈接是否有效,是否可正常打開.

System.Data.Entity.Core.ProviderIncompatibleException: 提供程序未返回 ProviderManifestToken 字符串。
---> MySql.Data.MySqlClient.MySqlException: Unable to connect to any of the specified MySQL hosts.

Error B.出現MySqlException此類問題可能是未安裝Connector/Net驅動 可到官網下載 https://dev.mysql.com/downloads/connector/net/

此步,在VS2017中不須要。

未解析成員「MySql.Data.MySqlClient.MySqlException,MySql.Data, Version=6.9.9.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d」的類型。
相關文章
相關標籤/搜索