Configuring Entity Framework Core Migrations for WPF Projects

WPF applications targeting .NET 5 or later often encounter issues when generating database migrasions with Entity Framework Core. The tooling fails to instantiate the DbContext because the design-time environment lacks the necessary startup configuration. Implementing the IDesignTimeDbContextFactory interface resolves this by providing an explicit creation path for the context.

Implementing the Design-Time Factory

Create a class that implements IDesignTimeDbContextFactory. This class must be located in the startup project or the project containing the context. The generic type parameter must match the specific context class being used.

public class DesignTimeContextFactory : IDesignTimeDbContextFactory<AppDatabaseContext>
{
    public AppDatabaseContext CreateDbContext(string[] args)
    {
        var options = new DbContextOptionsBuilder<AppDatabaseContext>()
            .UseSqlite("Filename=local_store.db")
            .Options;
            
        return new AppDatabaseContext(options);
    }
}

Context Configuration

The database context should handle connection strings gracefully, prioritizing options passed via the constructor while providing a fallback for design-time operations. Seed data can be configured within OnModelCreating.

public class AppDatabaseContext : DbContext
{
    public DbSet<Account> Accounts { get; set; }
    public DbSet<Role> Roles { get; set; }

    public AppDatabaseContext(DbContextOptions<AppDatabaseContext> options) 
        : base(options) { }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        if (!optionsBuilder.IsConfigured)
        {
            optionsBuilder.UseSqlite("Data Source=app_data.db");
        }
        
        base.OnConfiguring(optionsBuilder);
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<Role>().HasData(
            new Role { Id = 101, Title = "Contributor", Description = "Standard access" },
            new Role { Id = 102, Title = "Supervisor", Description = "Administrative access" }
        );

        modelBuilder.Entity<Account>().HasData(
            new Account 
            { 
                Id = 1001, 
                Username = "demo_user", 
                Passcode = "secure_pwd", 
                RegisteredAt = DateTime.UtcNow, 
                RoleId = 101 
            },
            new Account 
            { 
                Id = 1002, 
                Username = "system_admin", 
                Passcode = "admin_pwd", 
                RegisteredAt = DateTime.UtcNow, 
                RoleId = 102 
            }
        );
    }
}

Prerequisites

Ensure the following NuGet packages are installed in the project:

  • Microsoft.EntityFrameworkCore
  • Microsoft.EntityFrameworkCore.Sqlite
  • Microsoft.EntityFrameworkCore.Tools

The connection string defined in the factory or OnConfiguring must be valid and accessible during the design-time process. This approach applies similar to other providers like MySQL or PostgreSQL.

Executing Migrations

Migration commands are executed via the Package Manager Console or the .NET CLI. Ensure the correct project is selected as the startup project.

To create a new migration snapshot:

Add-Migration InitialCreate -Context AppDatabaseContext

To apply pending changes to the database:

Update-Database

If using the .NET CLI:

dotnet ef migrations add InitialCreate
dotnet ef database update

Tags: WPF Entity Framework Core .NET 5 sqlite database migration

Posted on Mon, 27 Jul 2026 16:12:43 +0000 by jasonman1