Skip to main content

Execute Data Migration

Before performing the migration, you need to be sure that your environment is properly prepared. At the time of writing this documentation, my environment consists of the following:

ToolVersion
.NET SDK7.0.306
dotnet-ef7.0.9
SQL Server2022 Developer Edition
SQL Server Management Studio19.1
Azure Data Studio1.45.0

Additionally, you should have access to a SQL Server with AdventureWorks installed.

The database configuration can be found in connections.json:

connections.json
{
"Origin": {
"Server": ".\\DevSql",
"Database": "AdventureWorks2022"
},
"Target": {
"Server": ".\\DevSql",
"Database": "v2-schema"
},
"ConnectionStrings": {
"Migration": "Server=.\\DevSql;Trusted_Connection=true;TrustServerCertificate=true;Database=v2-migration"
}
}
tip

If you need to consolidate multiple origin databases into a single target database, run the migration with different connections.json files where each origin database has a corresponding origin ConnectorConfig and migration connection string.

The migration and target databases should always be in sync. If on of these databases is removed and you want to perform a new migration, the other database should also be removed prior to the migration.

Database Preparation

The migration and target databases have corresponding Entity Framework configuration in this project:

This project also defines tasks for dropping and updating these databases:

Alternatively, these commands can be executed from a terminal:

TaskDirectoryCommand
Drop App DB/src/Appdotnet ef database drop -f
Update App DB/src/Appdotnet ef database update
Drop Migration DB/src/Coredotnet ef database drop -f
Update Migration DB/src/Coredotnet ef database update
info

Each of the following section start off assuming that you are starting with a blank migration and target database. The CLI automatically initializes the migration database according to the connection string if it does not exist, so you only need to drop the database between CLI runs. The target database, however, does not and needs to be dropped and updated between CLI runs.

Additionally, all of the CLI runs are executed from the /src/Cli/bin/Debug/net7.0/ directory after the project has been built.

Migrate a Single Entity

The simplest form of data migration is to migrate a table that has no dependencies via its migration command. Doing so will only import the data from that specific table and nothing else.

To demonstrate this, run .\migrator.exe migrate department:

Querying the target database, you can see that the Department records have been successfully migrated:

Migrate DepartmentMigrate Department

Additionally, querying the migration database, you can see that the recorded migration logs:

Migrate Department LogsMigrate Department Logs

Migrate Entities Recursively

If you're performing a fresh migrating targeting a table with dependencies, the migrated data will include the records for the dependent data along with the targeted table records.

To demonstrate this, run .\migrator.exe migrate employee:

Querying the target database, you can see that the Employee records have been migrated along with their dependent Department records:

Migrate RecursiveMigrate Recursive

info

If .\migrator.exe migrate contactinfo had been run instead, all ContactInfo records would have also caused their dependent Employee records to be migrated as well as their dependent Department records.

By building in calls to Translator.EnsureMigrated for each dependency inside of an OnMigrate callback, we can ensure that the full dependency tree is migrated recursively.

Additionally, querying the migration database, you can see the recorded migration logs:

Migrate Recursive LogsMigrate Recursive

Full Migration

Performing a full migration will execute the Translator.Migrate() migrations in the order they are specified in the FullCommand.

To demonstrate this, run .\migrator.exe migrate full:

Querying the target database, you can see that all records from all tables have been migrated:

Migrate FullMigrate Full

info

If data were ever migrated as a dependency before the migration for its table is executed, that record would be skipped during the validation phase since the record with that key would already be in the migration database. This ensures that there is no duplication of records polluting the migration.

Additionally, querying the migration database, you can see the recorded migration logs:

Migrate Full LogsMigrate Full Logs