Skip to main content

Keep Your Database In Sync With Application: Fluent Migrator

In this post, we continue to explore ways to free your application from being tightly bound to the Entity Framework environment. The primary goal is to offer an alternative solution that is not only more flexible and robust but also gives you, as a developer, greater control over database manipulation with less abstraction and complexity. Here, we introduce a library for database migrations, which serves as a natural extension to tools like Dapper and SqlKata.


Fluent Migrator

Fluent Migrator is a library designed for managing database migrations, giving you complete control over the execution and how migrations are written. It offers greater flexibility compared to standard EF migrations, which are closely tied to EF entities and generated automatically, often accompanied by additional overhead, including extra snapshot files.

In the code snippet below, you’ll find a simple migration class. This class includes two methods that override the base Migration class, allowing you to define your migration. This is all you need to create a migration.


using FluentMigrator;

[Migration(2025011801)]
public class Mig2025011801Init : Migration
{
    public override void Up()
    {
        Create.Table("Company")
            .WithColumn("Id").AsInt32().PrimaryKey().Identity()
            .WithColumn("Name").AsString(255).NotNullable()
    }

    public override void Down()
    {
        Delete.Table("Company");
    }
}

Additionally, when starting the project, we need to configure FluentMigrator to locate the migration classes and define how they should be executed. This is demonstrated in the code snippet below.


using FluentMigrator.Runner;
using Microsoft.Extensions.DependencyInjection;

class Program
{
    static void Main(string[] args)
    {
        var serviceProvider = CreateServices();

        using (var scope = serviceProvider.CreateScope())
        {
            UpdateDatabase(scope.ServiceProvider);
        }
    }

    private static IServiceProvider CreateServices()
    {
        return new ServiceCollection()
            .AddFluentMigratorCore()
            .ConfigureRunner(rb => rb
                .AddSqlServer()
                .WithGlobalConnectionString("conn string")
                .ScanIn(typeof(Mig2025011801Init).Assembly).For.Migrations())
            .AddLogging(lb => lb.AddFluentMigratorConsole())
            .BuildServiceProvider(false);
    }

    private static void UpdateDatabase(IServiceProvider serviceProvider)
    {
        var runner = serviceProvider.GetRequiredService<IMigrationRunner>();
        runner.MigrateUp();
    }
}



Conclusion

In conclusion, let us show one table where we see simple comparison between FluentMigrator and EF migrations. This can help you to decide which migration library to use for your next or existing project.


Fluent Migrator EF Migrations
Schema migrations for databases with full control over structure Built-in to EF for schema migrations tied to EF models
Independent of ORM (works with raw ADO.NET, Dapper, or others) Closely integrated with Entity Framework
Requires writing migrations manually, which can be verbose but provides full control. Migrations are auto-generated and customizable in C#.
Allows full control, suitable for existing schemas Focused on Code First or Model First approaches
Explicitly define Down() methods for each migration. Provides precise control over rollback logic Rollbacks involve reverting migrations using commands like Update-Database -TargetMigration
Integrates well into CI/CD pipelines as a standalone migration tool. Can be used independently of application deployment Integrated into EF workflows, making deployment tied to EF-related commands. Often relies on the application's context to execute migrations

Comments

Popular posts from this blog

Design Patterns: Singleton

Tyipically the first design pattern most people learn, often wrongly ☺ To give an introduction, we can say that singleton is one of the creational design patterns which ensures only one class instance with single point of access thru entire application.  Because it is relatively simple to implement, the Singleton pattern is sometimes misapplied in situations where it is not the most suitable choice. When to use it? Here are the few examples of corrent usage of singleton: Configuration Management  Centralized configuration settings for consistent use thru entire application Caching Maintaning  Single istance of cached objects for easy and fast acces Logging  Ensure unified mechanism to avoid duplication of log files, formats, etc Global State Management  Centralized management of the state which is needed to be shared accross the application Resource sharing  Thread pools, database connection, I/O operations When not to use it? On the other hand, here are fe...

Design Patterns: Builder

This is also, like a Singleton , one of the creational design patterns. It provides the way of creating complex objects step by step by simple chaining and every particular step is independent of other steps. Let us dive into the real example of usage. For showing purpose we have created an example in C# which creates simple SQL queries using described pattern.  using System; using System.Text; namespace BuilderPatternExample { public interface ISqlQueryBuilder { ISqlQueryBuilder Select(string columns); ISqlQueryBuilder From(string table); ISqlQueryBuilder Where(string condition); ISqlQueryBuilder OrderBy(string columns); string Build(); } public class SelectQueryBuilder : ISqlQueryBuilder { private readonly StringBuilder _queryBuilder; public SelectQueryBuilder() { _queryBuilder = new StringBuilder(); } public ISqlQueryBuilder Select(string columns) { ...

Why Do Employers Lie In Interviews?

This is a very common subject that many of us have already experienced. But when you realize that half of what has been said at interviews is actually a lie, you are already at least six months in the company, you have already started some project and it wouldn’t be appropriate to leave the company at that moment. Why is this happening? First of all, let us see how the usual interview process looks like in software development companies. First round interview in most of these companies is an interview with HR. This is the first insight about the company. A person who works in HR is usually someone who, in most cases, doesn’t understand what the software is and how the software development process goes. Big respect to those companies where HR knows these things. This phase usually contains some standard questions about your personality, what do you like about the company, how this company is something that you are actually looking for, where you see yourself in five/ten  years etc… ...