Applying migrations

So far, we applied all migrations using Visual Studio. This works really well when developers are working on features inside Visual Studio. However, when it comes to updating, testing, or production environments, this approach does not really work.

In order to update such software installations, we are given more options, which are as follows:

  • Generate the changes script
  • Use migrate.exe
  • Use the migrating initializer

Applying migrations via a script

We can easily generate a script by running the Update-Database commandlet with the Script parameter inside the same Package Manager Console window, using the following code line:

Update-Database -Script

As soon as this commandlet completes, the generated script will be opened. It will contain all the required changes to bring the structure of the target database up to date. We just need to give this script to our DBA, who will maintain our production environment.

Tip

We need to specify the correct connection string to the database that matches our target environment, since the migrations API compares the live database with the context from the data folder. We can use either another parameter to Update-Database and provide this connection string, or use a proper connection string in the configuration file that is used by our Data project.

Applying migrations via migrate.exe

Migrate.exe is a utility that is shipped with Entity Framework. It will be located in the same NuGet package folder as the Entity Framework DLL itself. We just need to distribute this utility with the binaries folder of our application to allow the utility to find all the assemblies it needs to work. This utility takes the same parameters as the Update-Database commandlet, for example:

migrate.exe Chapter7.VB.data 
/connectionString="Data Source=.;Initial Catalog=Chapter7;IntegratedSecurity=SSPI" 
/connectionProviderName="System.Data.SqlClient"
/startupConfigurationFile=Chapter7.VB.exe.config

We separated the command line into multiple lines for clarity, putting each argument on its own line for readability. The first argument is the assembly containing our context and migrations. Then, we specify the connection string, provider, and configuration file. We need the configuration file because our context's constructor is set up to take the connection string name from the configuration file.

Applying migrations via an initializer

We already saw how to use an initializer to recreate a database when structural changes are required. Entity Framework comes with an initializer base class that can be used to apply pending migrations. The base class is called MigrateDatabaseToLatestVersion. Here is how we define our initializer:

public class Initializer : 
    MigrateDatabaseToLatestVersion<Context, Configuration>
{
}

This is a very simple class; there is no code we need to write for it, unless we want to use the InitializeDatabase method, which allows us to run some code when migrations are applied. This method gets an instance of our DbContext object, thus we can add more data to the database in this method or perform other functions. Here is how this code looks in VB.NET:

Public Class Initializer
    inherits MigrateDatabaseToLatestVersion(Of Context, Configuration)
End Class

Alternatively, we can use our migration configuration class, which has the familiar Seed method to populate our database with some seeded data.

Now, we just need to plug this new initializer into Entity Framework at the application startup time and call the context to force migrations to be applied, as shown in the following code snippet:

Database.SetInitializer(new Initializer());
using (var context = new Context())
{
    context.Database.Initialize(true);
}

We already saw similar code when we worked with other initializers. Here, we also call the Initialize method on the database to force schema verification and migrations application on an existing database. If the database does not exist, it will be created. Here is how the code looks in VB.NET:

Database.SetInitializer(new Initializer)
Using context = new Context
    context.Database.Initialize(True)
End Using

We do not have to call the initialization method at the application start up time; it will automatically run during the first query execution. This code just makes migration application time more predictable.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.36.38