程式碼型組態

注意

僅限 EF6 及更新版本 - Entity Framework 6 已引進此頁面中所討論的功能及 API 等等。 如果您使用的是較早版本,則不適用部分或全部的資訊。

Entity Framework 應用程式的組態可以在組態檔 (app.config/web.config) 或透過程式碼指定。 後者稱為程式碼型組態。

組態檔中的組態會在另一 篇文章 中說明。 組態檔的優先順序高於程式碼型組態。 換句話說,如果在程式碼和組態檔中設定組態選項,則會使用組態檔中的設定。

使用 DbConfiguration

EF6 和更新版本的程式碼型組態是藉由建立 的 System.Data.Entity.Config.DbConfiguration 子類別來達成。 子類別 DbConfiguration 化時,應該遵循下列指導方針:

  • 只為您的應用程式建立一個 DbConfiguration 類別。 這個類別會指定整個應用程式域的設定。
  • 將您的 DbConfiguration 類別放在與類別 DbContext 相同的元件中。 (請參閱 如果您想要變更此專案,請移動 DbConfiguration 區段。
  • DbConfiguration為您的類別提供公用無參數建構函式。
  • 從這個建構函式內呼叫受保護的 DbConfiguration 方法,以設定組態選項。

遵循這些指導方針可讓 EF 透過需要存取模型和應用程式執行時機的工具,自動探索及使用您的設定。

範例

衍生自 DbConfiguration 的類別看起來可能如下所示:

using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.SqlServer;

namespace MyNamespace
{
    public class MyConfiguration : DbConfiguration
    {
        public MyConfiguration()
        {
            SetExecutionStrategy("System.Data.SqlClient", () => new SqlAzureExecutionStrategy());
            SetDefaultConnectionFactory(new LocalDbConnectionFactory("mssqllocaldb"));
        }
    }
}

此類別會將 EF 設定為使用 SQL Azure 執行策略 - 自動重試失敗的資料庫作業 , 以及針對從 Code First 建立的資料庫使用 Local DB。

移動 DbConfiguration

在某些情況下,無法將類別放在與類別 DbConfiguration 相同的元件 DbContext 中。 例如,您可能在不同的元件中各有兩 DbContext 個類別。 有兩個選項可以處理此作業。

第一個選項是使用組態檔來指定要 DbConfiguration 使用的實例。 若要這樣做,請設定 entityFramework 區段的 codeConfigurationType 屬性。 例如:

<entityFramework codeConfigurationType="MyNamespace.MyDbConfiguration, MyAssembly">
    ...Your EF config...
</entityFramework>

codeConfigurationType 的值必須是類別 DbConfiguration 的元件和命名空間限定名稱。

第二個選項是在內容類別別上放置 DbConfigurationTypeAttribute 。 例如:

[DbConfigurationType(typeof(MyDbConfiguration))]
public class MyContextContext : DbContext
{
}

傳遞至 屬性的值可以是您的 DbConfiguration 類型 ,如上所示,或是元件和命名空間限定型別名稱字串。 例如:

[DbConfigurationType("MyNamespace.MyDbConfiguration, MyAssembly")]
public class MyContextContext : DbContext
{
}

明確設定 DbConfiguration

在某些情況下,可能需要設定,才能使用任何 DbContext 類型。 此範例包括:

  • 使用 DbModelBuilder 來建置沒有內容的模型
  • 使用一些其他架構/公用程式程式碼,利用 DbContext 在應用程式內容使用之前使用該內容的位置

在這種情況下,EF 無法自動探索設定,您必須改為執行下列其中一項:

  • DbConfiguration如上述移動 DbConfiguration 一節所述 ,設定組態檔中的類型
  • 呼叫靜態 DbConfiguration 。應用程式啟動時的 SetConfiguration 方法

重寫 DbConfiguration

在某些情況下,您需要覆寫 中的 DbConfiguration 組態集。 這通常不是由應用程式開發人員完成,而是由無法使用衍生 DbConfiguration 類別的協力廠商提供者和外掛程式來完成。

因此,EntityFramework 允許註冊事件處理常式,以在鎖定現有組態之前修改現有組態。 它也提供糖方法,專門用來取代 EF 服務定位器所傳回的任何服務。 這是其用途:

  • 在應用程式啟動時(使用 EF 之前),外掛程式或提供者應該註冊此事件的事件處理常式方法。 (請注意,這必須在應用程式使用 EF 之前發生。
  • 事件處理常式會針對需要取代的每個服務呼叫 ReplaceService。

例如,若要取代 IDbConnectionFactory ,而 DbProviderService 您會註冊類似如下的處理常式:

DbConfiguration.Loaded += (_, a) =>
   {
       a.ReplaceService<DbProviderServices>((s, k) => new MyProviderServices(s));
       a.ReplaceService<IDbConnectionFactory>((s, k) => new MyConnectionFactory(s));
   };

在上述程式碼中, MyProviderServicesMyConnectionFactory 代表服務的實作。

您也可以新增其他相依性處理常式,以取得相同的效果。

請注意,您也可以以這種方式包裝 DbProviderFactory ,但這樣做只會影響 EF,而不會影響 EF 外部的使用 DbProviderFactory 。 基於這個理由,您可能會想要繼續包裝 DbProviderFactory ,就像之前一樣。

您也應該記住從 封裝管理員 主控台執行移轉時,從應用程式外部執行的服務。 當您從主控台執行移轉時,會嘗試尋找您的 DbConfiguration 。 不過,它是否會取得包裝的服務,取決於它註冊的事件處理常式位置。 如果它註冊為建構的 DbConfiguration 一部分,則程式碼應該執行,服務應該包裝。 通常情況不會如此,這表示工具不會取得包裝的服務。