コードベースの構成Code-based configuration

注意

EF6 以降のみ - このページで説明する機能、API などは、Entity Framework 6 で導入されました。EF6 Onwards Only - The features, APIs, etc. discussed in this page were introduced in Entity Framework 6. 以前のバージョンを使用している場合、一部またはすべての情報は適用されません。If you are using an earlier version, some or all of the information does not apply.

Entity Framework アプリケーションの構成は、構成ファイル (app.config/web.config) またはコードを使用して指定できます。Configuration for an Entity Framework application can be specified in a config file (app.config/web.config) or through code. 後者は、コードベースの構成と呼ばれます。The latter is known as code-based configuration.

構成ファイルの構成については、 別の記事で説明します。Configuration in a config file is described in a separate article. 構成ファイルは、コードベースの構成よりも優先されます。The config file takes precedence over code-based configuration. つまり、構成オプションがコードと構成ファイルの両方で設定されている場合、構成ファイルの設定が使用されます。In other words, if a configuration option is set in both code and in the config file, then the setting in the config file is used.

DbConfiguration の使用Using DbConfiguration

EF6 以降のコードベースの構成は、System.Data.Entity.Config のサブクラスを作成することによって実現されます。DbConfiguration.Code-based configuration in EF6 and above is achieved by creating a subclass of System.Data.Entity.Config.DbConfiguration. DbConfiguration をサブクラス化する場合は、次のガイドラインに従う必要があります。The following guidelines should be followed when subclassing DbConfiguration:

  • アプリケーションの DbConfiguration クラスを1つだけ作成します。Create only one DbConfiguration class for your application. このクラスは、アプリドメイン全体の設定を指定します。This class specifies app-domain wide settings.
  • DbConfiguration クラスを Dbconfiguration クラスと同じアセンブリに配置します。Place your DbConfiguration class in the same assembly as your DbContext class. (これを変更する場合は、「 DbConfiguration の移動 」セクションを参照してください)。(See the Moving DbConfiguration section if you want to change this.)
  • DbConfiguration クラスにパブリックのパラメーターなしのコンストラクターを指定します。Give your DbConfiguration class a public parameterless constructor.
  • このコンストラクター内から保護された DbConfiguration メソッドを呼び出すことによって、構成オプションを設定します。Set configuration options by calling protected DbConfiguration methods from within this constructor.

これらのガイドラインに従うことで、EF は、モデルにアクセスする必要があるツールとアプリケーションの実行時の両方で、構成を自動的に検出して使用できるようになります。Following these guidelines allows EF to discover and use your configuration automatically by both tooling that needs to access your model and when your application is run.

Example

DbConfiguration から派生したクラスは次のようになります。A class derived from DbConfiguration might look like this:

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"));
        }
    }
}

このクラスは、SQL Azure の実行戦略を使用するように EF を設定します。これにより、失敗したデータベース操作を自動的に再試行し、Code First から規則によって作成されたデータベースに対してローカル DB を使用します。This class sets up EF to use the SQL Azure execution strategy - to automatically retry failed database operations - and to use Local DB for databases that are created by convention from Code First.

DbConfiguration の移動Moving DbConfiguration

DbConfiguration クラスを Dbconfiguration クラスと同じアセンブリに配置できない場合があります。There are cases where it is not possible to place your DbConfiguration class in the same assembly as your DbContext class. たとえば、それぞれ異なるアセンブリに2つの DbContext クラスがあるとします。For example, you may have two DbContext classes each in different assemblies. この処理には、2つのオプションがあります。There are two options for handling this.

1つ目のオプションは、構成ファイルを使用して、使用する DbConfiguration インスタンスを指定する方法です。The first option is to use the config file to specify the DbConfiguration instance to use. これを行うには、entityFramework セクションの codeConfigurationType 属性を設定します。To do this, set the codeConfigurationType attribute of the entityFramework section. 次に例を示します。For example:

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

CodeConfigurationType の値は、アセンブリおよび DbConfiguration クラスの名前空間修飾名である必要があります。The value of codeConfigurationType must be the assembly and namespace qualified name of your DbConfiguration class.

2つ目の方法は、コンテキストクラスに DbConfigurationTypeAttribute を配置することです。The second option is to place DbConfigurationTypeAttribute on your context class. 次に例を示します。For example:

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

属性に渡す値は、上に示すように DbConfiguration 型にするか、アセンブリと名前空間で修飾された型名の文字列にすることができます。The value passed to the attribute can either be your DbConfiguration type - as shown above - or the assembly and namespace qualified type name string. 次に例を示します。For example:

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

DbConfiguration を明示的に設定するSetting DbConfiguration explicitly

DbContext 型を使用する前に構成が必要になる状況もあります。There are some situations where configuration may be needed before any DbContext type has been used. この例には以下のようなものがあります。Examples of this include:

  • DbModelBuilder を使用してコンテキストなしでモデルを構築するUsing DbModelBuilder to build a model without a context
  • アプリケーションコンテキストが使用される前にそのコンテキストが使用される DbContext を利用する他のフレームワーク/ユーティリティコードを使用するUsing some other framework/utility code that utilizes a DbContext where that context is used before your application context is used

このような状況では、EF は構成を自動的に検出できないため、代わりに次のいずれかを実行する必要があります。In such situations EF is unable to discover the configuration automatically and you must instead do one of the following:

  • 上の「 DbConfiguration の移動 」セクションで説明したように、構成ファイルで dbconfiguration 型を設定します。Set the DbConfiguration type in the config file, as described in the Moving DbConfiguration section above
  • アプリケーションの起動時に、静的な DbConfiguration. SetConfiguration メソッドを呼び出します。Call the static DbConfiguration.SetConfiguration method during application startup

DbConfiguration のオーバーライドOverriding DbConfiguration

DbConfiguration で構成セットを上書きする必要がある状況もあります。There are some situations where you need to override the configuration set in the DbConfiguration. これは通常、アプリケーション開発者によって行われるのではなく、派生した DbConfiguration クラスを使用できないサードパーティプロバイダーやプラグインによって実行されます。This is not typically done by application developers but rather by third party providers and plug-ins that cannot use a derived DbConfiguration class.

このため、EntityFramework では、ロックダウンの直前に既存の構成を変更できるイベントハンドラーを登録できます。For this, EntityFramework allows an event handler to be registered that can modify existing configuration just before it is locked down. また、EF サービスロケーターによって返されるサービスを置き換えるための、砂糖の方法も提供します。It also provides a sugar method specifically for replacing any service returned by the EF service locator. これは、次のように使用することを意図しています。This is how it is intended to be used:

  • (EF が使用される前に) アプリの起動時に、プラグインまたはプロバイダーがこのイベントのイベントハンドラーメソッドを登録する必要があります。At app startup (before EF is used) the plug-in or provider should register the event handler method for this event. (これは、アプリケーションで EF を使用する前に行う必要があることに注意してください)。(Note that this must happen before the application uses EF.)
  • イベントハンドラーは、置き換える必要があるすべてのサービスに対して、交換用 Eservice を呼び出します。The event handler makes a call to ReplaceService for every service that needs to be replaced.

たとえば、IDbConnectionFactory と DbProviderService を置き換えるには、次のようなハンドラーを登録します。For example, to replace IDbConnectionFactory and DbProviderService you would register a handler something like this:

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

上記のコードでは、MyProviderServices と Myproviderservices がサービスの実装を表しています。In the code above MyProviderServices and MyConnectionFactory represent your implementations of the service.

また、依存関係ハンドラーを追加して同じ効果を得ることもできます。You can also add additional dependency handlers to get the same effect.

この方法で DbProviderFactory をラップすることもできますが、これを行うと EF にのみ影響し、EF の外部では DbProviderFactory を使用しないことに注意してください。Note that you could also wrap DbProviderFactory in this way, but doing so will only affect EF and not uses of the DbProviderFactory outside of EF. このため、以前と同じように引き続き DbProviderFactory をラップすることをお勧めします。For this reason you’ll probably want to continue to wrap DbProviderFactory as you have before.

また、パッケージマネージャーコンソールから移行を実行する場合など、アプリケーションの外部で実行するサービスについても考慮する必要があります。You should also keep in mind the services that you run externally to your application - for example, when running migrations from the Package Manager Console. コンソールから移行を実行すると、DbConfiguration の検索が試行されます。When you run migrate from the console it will attempt to find your DbConfiguration. ただし、ラップされたサービスを取得するかどうかは、イベントハンドラーの登録場所によって異なります。However, whether or not it will get the wrapped service depends on where the event handler it registered. DbConfiguration の構築の一部として登録されている場合は、コードを実行し、サービスをラップする必要があります。If it is registered as part of the construction of your DbConfiguration then the code should execute and the service should get wrapped. 通常、これは当てはまりません。これは、ツールがラップされたサービスを取得しないことを意味します。Usually this won’t be the case and this means that tooling won’t get the wrapped service.