首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

ADO.NET Entity Framework MySQL Provider 自建指南:從原始碼編譯到實戰部署

     編輯:關於.NET

早期 Entity Framework (EF) 官方僅支援 SQL Server,MySQL 需第三方 Provider。本文記錄從 MySQL 官方原始碼 (MySql.Data 5.3.0 + MySql.Data.Entity) 自行編譯、簽名、註冊 EF Provider 的完整流程,解決專案必須使用 MySQL 且預算有限無法購買商業版 Devart dotConnect 的實際需求。

原始碼取得與編譯

  1. 從 MySQL 官方原始碼倉庫下載 MySql.Data (5.3.0) 與新增的 MySql.Data.Entity 專案
  2. 先編譯 MySql.Data 並**強名簽名** (sn -k key.snk → 專案屬性 → 簽署)
  3. 編譯 MySql.Data.Entity 並參考剛簽名的 MySql.Data,同樣強名簽名
  4. 記錄 MySql.Data.Entity 的 PublicKeyToken (sn -T MySql.Data.Entity.dll)

修改 MySql.Data 註冊 EF 服務

編輯 MySqlClientFactory 的 IServiceProvider.GetService,指向自建的 Provider 實作:

private FieldInfo MySqlDbProviderServicesInstance {
    get {
        if (mySqlDbProviderServicesInstance == null) {
            string fullName = "MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity, Version=5.3.0.0, Culture=neutral, PublicKeyToken=b3fe30829fc170e4";
            Type providerServicesType = Type.GetType(fullName, false);
            mySqlDbProviderServicesInstance = providerServicesType.GetField("Instance",
                BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);
        }
        return mySqlDbProviderServicesInstance;
    }
}

object IServiceProvider.GetService(Type serviceType) {
    if (serviceType != DbServicesType) return null;
    if (MySqlDbProviderServicesInstance == null) return null;
    return MySqlDbProviderServicesInstance.GetValue(null);
}

關鍵:PublicKeyToken 必須與剛編譯的 MySql.Data.Entity 組件完全一致。

重新編譯並安裝 GAC

  1. 重新編譯 MySql.Data.dll 與 MySql.Data.Entity.dll
  2. 安裝至 GAC:gacutil /i MySql.Data.dll、gacutil /i MySql.Data.Entity.dll

機器設定註冊 Provider Factory

編輯 machine.config (通常在 %windir%\Microsoft.NET\Framework\v4.0.30319\Config\),在 <system.data><DbProviderFactories> 區段加入:

<add name="MySQL Data Provider" 
     invariant="MySql.Data.MySqlClient" 
     description=".Net Framework Data Provider for MySQL" 
     type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=5.3.0.0, Culture=neutral, PublicKeyToken=c66bfea3ae91850d" />

注意:此處 PublicKeyToken 必須對應 MySql.Data (非 Entity 組件)。

模型定義與測試驗證

資料庫建表

CREATE TABLE `mytable` (
  `ID` int(11) NOT NULL DEFAULT '0',
  `NAME` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

SSDL (儲存模型)

<Schema Namespace="TestModel.Store" Provider="MySql.Data.MySqlClient" ProviderManifestToken="MySQL" ...>
  <EntityContainer Name="Model3TargetContainer">
    <EntitySet Name="MYTABLE" EntityType="TestModel.Store.MYTABLE" store:Type="Tables" Schema="testdb" />
  </EntityContainer>
  <EntityType Name="MYTABLE">
    <Key><PropertyRef Name="ID" /></Key>
    <Property Name="ID" Type="int" Nullable="false" />
    <Property Name="NAME" Type="varchar" Nullable="true" MaxLength="40" />
  </EntityType>
</Schema>

CSDL (概念模型) 與 MSL (映射)

概念模型使用 Company 實體 (屬性 ID, Name),MSL 將 Company.Name 對應至資料表 NAME 欄位,Company.ID 對應 ID。

產生實體類別

edmgen /mode:EntityClassGeneration /incsdl:TestDB.csdl /namespace:Test /project:Test

實際查詢測試

using (var db = new Model3Container1(GetConnectionString())) {
    var coms = from c in db.Company where c.ID < 50 select c;
    foreach (var item in coms) Console.WriteLine(item.Name);
}

private static string GetConnectionString() {
    return $"metadata=TestDB.csdl|TestDB.msl|TestDB.ssdl;provider=MySql.Data.MySqlClient;provider connection string=\"User Id=root;Password=root;Host=192.168.1.152;Database=testdb;Persist Security Info=True\"";
}

風險與後續建議

  • 此組件為 MySQL 官方**預發布版本**,穩定性、相容性未經充分驗證
  • 生產環境建議:
  • 完整測試 CRUD、關聯載入、交易、並發場景
  • 關注 MySQL 官方正式釋出 EF Provider 版本
  • 評估升級至 EF Core + Pomelo.EntityFrameworkCore.MySQL (社群維護、活躍度高)

文末提供編譯完成的兩個 DLL 下載連結供參考測試。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved