DbContext クラスは、ConnectionString を使用してデータベースへの接続を確立します。
通常、DbContext によって公開される複数のモデル クラスがあります。
同じ接続文字列値を使用してデータベースに接続する複数の DbContext オブジェクトを持つことができます。このようにして、必要に応じて、モデルの一部を個別のコンテキストに分けることができます (たとえば、異なるテーブルにアクセスするがアプリケーションに同様のサービスを提供する個別のアセンブリを作成する場合)。
少なくとも 5.0 までの EF で注意すべき点が 1 つあります。複数の DbContext でコード ファーストの移行を使用することはできません。一方が他方の変更を上書きします。これに対する解決策は、移行プロセスにのみ使用される集約された DbContext を作成することです。
私が作成したアプリでこれを行いました。Unity IoC コンテナーを使用し、プラグイン インターフェイスを構築して、ConnectionStringName を分離した DbContext に渡すことができるようにしました。アセンブリの 1 つのプラグインの例は次のとおりです。
public class Bootstrapper : IBootstrapper
{
public void Bootstrap(IUnityContainer container, string connectionStringName)
{
container.RegisterType<ISQService, SQService>();
container.RegisterType<ISQEntities, SQEntities>(
new HierarchicalLifetimeManager(), new InjectionConstructor(connectionStringName));
container.RegisterType<IController, SQController>("SQ");
}
}
私の global.asax は、以下のブートストラップ クラスを参照しました。
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
ModelBinders.Binders[typeof(DataTable)] = new DataTableModelBinder();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
Bootstrapper.Initialise();
}
protected void Application_End()
{
Bootstrapper.Dispose();
}
ブートストラップ
public static class Bootstrapper
{
private static IUnityContainer container;
public static void Initialise()
{
container = BuildUnityContainer();
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
}
public static void Dispose()
{
container.Dispose();
}
private static void RegisterPlugins(IUnityContainer theContainer, string wildcard, string connectionStringName)
{
var pluginBootStrappers = from Assembly assembly in wildcard.LoadAssemblies()
from type in assembly.GetExportedTypes()
where typeof(IBootstrapper).IsAssignableFrom(type)
select (IBootstrapper)Activator.CreateInstance(type);
pluginBootStrappers.ToList().ForEach(b => b.Bootstrap(theContainer, connectionStringName));
}
private static IUnityContainer BuildUnityContainer()
{
var theContainer = new UnityContainer();
const string ConnectionStringName = "MyDb";
RegisterPlugins(theContainer, "MyApp.Systems.*.dll", ConnectionStringName);
// Register Application Specific objects
theContainer.RegisterType<IMyEntities, MyEntities>(
new HierarchicalLifetimeManager(),
new InjectionConstructor(ConnectionStringName));
theContainer.RegisterType<IAimaService, AimaService>();
var factory = new UnityControllerFactory(theContainer);
ControllerBuilder.Current.SetControllerFactory(factory);
return theContainer;
}
}