Multiple Contexts per Database in EF6
In EF5, migrations is only able to manage a single user model (DbContext) per physical database instance. In EF6 Migrations will be able to deal with managing multiple models per physical database instance.
Formerly Known as ‘Multi-Tenant Migrations’
Note: This feature was formerly referred to as Multi-Tenant Migrations. This named caused confusion because the feature does *not* enable using the same context multiple times in the same database. Instead, we are making the migrations table multi-tenant so that two distinct models can coexist in the same database.
There are two principal ways that multi-tenancy can be realized in EF6:
1. ContextKey
DbMigrationsConfiguration.ContextKey is a new Migrations configuration property in EF6. Its primary purpose is to allow the __MigrationHistory table to store metadata for more than a single model. To enable this, a corresponding column is being added to the history table thus making the table multi-tenant by ContextKey.
The default value for the ContextKey property is the fully-qualified type name of the parent DbMigrationsConfiguration (typically a user derived class). However, the actual value is arbitrary and can be user-specified in the standard way. I.e. In the constructor of the derived DbMigrationsConfiguration - Although, this should typically only happen before any migrations have been applied to a target database (otherwise the existing history rows will need to be updated to the new key value).
The DbContext Initializer infrastucture also uses the __MigrationHistory table to store model metadata. In this case, the default value of ContextKey becomes the fully-qualified derived DbContext type name. When "growing-up" from Initializers to Migrations, Migrations detects such initializer rows and automatically sets the ContextKey property to the existing value in the scaffolded DbMigrationsConfiguration.
1. Default Schema Propagation
DbModelBuilder.HasDefaultSchema is a new Code First API in EF6. Its purpose is to allow the default database schema for a Code First model to be configured in one place - Previously the Code First default schema was hard-coded to "dbo" and the only way to configure the schema to which a table belonged was via the ToTable API.
In EF6, the configured default schema will also affect the Migrations infrastructure, in particular, the Migrations history table (__MigrationHistory), which stores the Migrations version history for a given user model. In this way it will be possible to have multiple __MigrationHistory tables within a given physical database and thus support multi-tenancy via schema partitioning.
The default schema for a given model is free to change over the lifetime of the model. When Migrations detects a schema change, both user objects and the __MigrationHistory table are transferred to the new schema. However, for implementation reasons, transferring the __MigrationHistory table to a different schema can only occur using a code-based migration.
Enable-Migrations Enhancements
To better support migrating multiple models within a single Visual Studio project, a -MigrationsDirectory parameter is being added to the Enable-Migrations command in EF6. This parameter is analogous to the existing DbMigrationsConfiguration.MigrationsDirectory property and affects the following:
- The name of the project directory containing the scaffolded DbMigrationsConfiguration (and any subsequently scaffolded code-based migrations files).
- The namespace of the scaffolded DbMigrationsConfiguration i.e. matching the directory structure.
- Sets the MigrationsDirectory property in the scaffolded DbMigrationsConfiguration to the provided value.