You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WinUI3项目执行Add-Migration命令失败,求更优解决方案

解决WinUI3中Entity Framework Core迁移创建失败的问题

问题场景

在WinUI3项目中配置EF Core的BusinessDomainContext并通过依赖注入注册后,执行迁移命令:

Add-Migration InitialCreate -Context BusinessDomainContext -OutputDir Migrations\BusinessDomain

出现报错:

Unable to create an object of type 'BusinessDomainContext'. For the different patterns supported at design time, see ...

当前临时方案是借助控制台项目作为启动项目执行迁移,以下是更优的本地解决方案:

方案1:添加设计时DbContext工厂(推荐)

这是EF Core官方针对设计时实例化DbContext的标准方案,无需依赖WinUI的DI容器,也不用切换启动项目:

在项目中创建如下类,EF Core设计时工具会自动识别并使用它创建DbContext实例:

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using System.Configuration;

public class BusinessDomainContextFactory : IDesignTimeDbContextFactory<BusinessDomainContext>
{
    public BusinessDomainContext CreateDbContext(string[] args)
    {
        var optionsBuilder = new DbContextOptionsBuilder<BusinessDomainContext>();
        string connectionString = ConfigurationManager.AppSettings["BusinessDomainConnectionString"];
        optionsBuilder.UseSqlServer(connectionString);

        return new BusinessDomainContext(optionsBuilder.Options);
    }
}

方案2:为DbContext添加设计时专用无参构造

在BusinessDomainContext中添加仅用于设计时的无参构造,直接配置连接字符串(注意:生产环境建议移除该构造,避免配置泄露风险):

public class BusinessDomainContext : DbContext
{
    public DbSet<Subject> Subjects { get; set; }
    public DbSet<Test> Tests { get; set; }

    // 生产环境使用的构造
    public BusinessDomainContext(DbContextOptions<BusinessDomainContext> options) : base(options) { }

    // 仅设计时迁移使用,生产环境可注释/删除
    public BusinessDomainContext()
    {
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        if (!optionsBuilder.IsConfigured)
        {
            string connectionString = ConfigurationManager.AppSettings["BusinessDomainConnectionString"];
            optionsBuilder.UseSqlServer(connectionString);
        }
    }
}

方案3:复用现有DI配置创建设计时实例

调整App类的DI配置为非静态,并创建设计时工厂复用该配置:

  1. 修改App.xaml.cs,保留ServiceProvider实例:
public IServiceProvider? Services { get; private set; }

public App()
{
    Services = ConfigureServices();
    this.InitializeComponent();
}

private IServiceProvider ConfigureServices()
{
    var services = new ServiceCollection();

    SetupLogger(services);

    string businessDomainConnection = ConfigurationManager.AppSettings["BusinessDomainConnectionString"];

    services.AddDbContext<BusinessDomainContext>(options =>
    {
        options.UseSqlServer(businessDomainConnection);
    });

    return services.BuildServiceProvider();
}
  1. 创建设计时工厂,通过App的ServiceProvider获取DbContext:
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.Extensions.DependencyInjection;

public class BusinessDomainContextFactory : IDesignTimeDbContextFactory<BusinessDomainContext>
{
    public BusinessDomainContext CreateDbContext(string[] args)
    {
        var app = new App();
        return app.Services!.GetRequiredService<BusinessDomainContext>();
    }
}

方案选择建议

优先选择方案1,它完全独立于WinUI应用生命周期,专为设计时场景设计,不会干扰生产代码的结构与安全性。

内容的提问来源于stack exchange,提问作者RezaNoei

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 14:52:55