Single Layer Solution: Db Migrator

Unlike the Layered solution template, the Single Layer solution template does not include a separate database migrator project. Instead, the main application project handles database migration and seed data operations. The *.DbMigrator project is excluded from this template. To manage database migrations and seed data, you can use the migrate-database.ps1 script in the root directory or run the dotnet run --migrate-database command from the main application project directory.

Single Layer Solution: Db Migrator

After the migration completes, a message will appear in the console. You can verify the success of the migration by checking the database.

Database Migration Service

Under the Data folder of the project, the BookstoreDbMigrationService class is responsible for database migration and seed data operations. The MigrateAsync method is called in the Program class to migrate the database when the application starts with the --migrate-database argument.

First, it checks if the database is created and applies the pending migrations. Then, it seeds the initial data using the SeedAsync method.

public async Task MigrateAsync()
{
    var initialMigrationAdded = AddInitialMigrationIfNotExist();

    if (initialMigrationAdded)
    {
        return;
    }

    Logger.LogInformation("Started database migrations...");

    await MigrateDatabaseSchemaAsync();
    await SeedDataAsync();

    Logger.LogInformation($"Successfully completed host database migrations.");

    var tenants = await _tenantRepository.GetListAsync(includeDetails: true);

    var migratedDatabaseSchemas = new HashSet<string>();
    foreach (var tenant in tenants)
    {
        using (_currentTenant.Change(tenant.Id))
        {
            if (tenant.ConnectionStrings.Any())
            {
                var tenantConnectionStrings = tenant.ConnectionStrings
                    .Select(x => x.Value)
                    .ToList();

                if (!migratedDatabaseSchemas.IsSupersetOf(tenantConnectionStrings))
                {
                    await MigrateDatabaseSchemaAsync(tenant);

                    migratedDatabaseSchemas.AddIfNotContains(tenantConnectionStrings);
                }
            }

            await SeedDataAsync(tenant);
        }

        Logger.LogInformation($"Successfully completed {tenant.Name} tenant database migrations.");
    }

    Logger.LogInformation("Successfully completed all database migrations.");
    Logger.LogInformation("You can safely end this process...");
}

The BookstoreDbSchemaMigrator class is used in the MigrateDatabaseSchemaAsync method for the database migration process. It is responsible for applying migrations to the database.

public class BookstoreDbSchemaMigrator : ITransientDependency
{
    private readonly IServiceProvider _serviceProvider;

    public BookstoreDbSchemaMigrator(
        IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    public async Task MigrateAsync()
    {
        
        /* We intentionally resolving the BookstoreDbContext
         * from IServiceProvider (instead of directly injecting it)
         * to properly get the connection string of the current tenant in the
         * current scope.
         */

        await _serviceProvider
            .GetRequiredService<BookstoreDbContext>()
            .Database
            .MigrateAsync();

    }
}

Contributors


Last updated: December 25, 2024 Edit this page on GitHub

Was this page helpful?

Please make a selection.

To help us improve, please share your reason for the negative feedback in the field below.

Please enter a note.

Thank you for your valuable feedback!

Please note that although we cannot respond to feedback, our team will use your comments to improve the experience.

In this document
Community Talks

Layered vs Modular vs Microservices... Which one is best for you?

09 Jan, 17:00
Online
Watch the Event
Mastering ABP Framework Book
Mastering ABP Framework

This book will help you gain a complete understanding of the framework and modern web application development techniques.

Learn More