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

以编程方式生成EF Core迁移失败:后续迁移创建报错求助

EF Core 后续迁移创建失败问题

开发控制台应用用于为引用程序集生成并应用EF Core Migrations,首次迁移可成功创建,但尝试后续迁移时抛出以下异常:

System.InvalidOperationException: The model must be finalized and its runtime dependencies must be initialized before 'GetRelationalModel' can be used. Ensure that either 'OnModelCreating' has completed or, if using a stand-alone 'ModelBuilder', that 'IModelRuntimeInitializer.Initialize(model.FinalizeModel())' was called.
   at Microsoft.EntityFrameworkCore.RelationalModelExtensions.GetRelationalModel(IModel model)
   at Microsoft.EntityFrameworkCore.Migrations.Design.MigrationsScaffolder.ScaffoldMigration(String migrationName, String rootNamespace, String subNamespace, String language)

相关代码

迁移生成核心逻辑(已省略文件写入等无关代码)

var references = new[]
{
    typeof(object).GetTypeInfo().Assembly.Location,
    typeof(Console).GetTypeInfo().Assembly.Location,
    typeof(MigrationBuilder).GetTypeInfo().Assembly.Location,
    typeof(ModelBuilder).GetTypeInfo().Assembly.Location,
    typeof(Action).GetTypeInfo().Assembly.Location,
    typeof(Expression<>).GetTypeInfo().Assembly.Location,
    typeof(System.Runtime.AssemblyTargetedPatchBandAttribute).GetTypeInfo().Assembly.Location,
    typeof(BinaryExpression).GetTypeInfo().Assembly.Location,
    AppDomain.CurrentDomain.GetAssemblies().Single(a => a.GetName().Name == "netstandard").Location,
    Path.Combine(Path.GetDirectoryName(typeof(System.Runtime.GCSettings).GetTypeInfo().Assembly.Location),
                "System.Runtime.dll"),
}.Select(r => MetadataReference.CreateFromFile(r)).ToArray();
        
var ctxType = dbContext.GetType();
var ctxAssemblyRefPath = ctxType.GetTypeInfo().Assembly.Location;
var ctxAssemblyMetaData = MetadataReference.CreateFromFile(ctxAssemblyRefPath);

// migrationsDirectory包含已生成的迁移类和模型快照类
var migrationsDirectory = GetMigrationsDirectory();
var assemblyName = Path.GetRandomFileName();
        
var syntaxTrees = Directory
    .GetFiles(migrationsDirectory)
    .Select(File.ReadAllText)
    .Select(f => CSharpSyntaxTree.ParseText(f));

var compilation = CSharpCompilation.Create(
    assemblyName,
    syntaxTrees,
    references: references.Concat(new[] { ctxAssemblyMetaData }),
    options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));

using var ms = new MemoryStream();

compilation.Emit(ms);
ms.Seek(0, SeekOrigin.Begin);
            
var assembly = AssemblyLoadContext.Default.LoadFromStream(ms);
var prop = ctxType.BaseType?.GetProperty("MigrationAssembly");
prop.SetValue(null, assembly.GetName().FullName);
            
var ctxInstance = Activator.CreateInstance(ctxType) as GwrsDbContext;
            
designTimeServices = new ServiceCollection()
                .AddSingleton<IOperationReporter>(new OperationReporter(null))
                .AddSingleton<MigrationsCodeGeneratorDependencies>()
                .AddSingleton<ValueConverterSelectorDependencies>()
                .AddSingleton<IValueConverterSelector, ValueConverterSelector>()
                .AddSingleton<TypeMappingSourceDependencies>()
                .AddSingleton<RelationalTypeMappingSourceDependencies>()
                .AddSingleton<ITypeMappingSource, RelTypeMappingSource>()
                .AddSingleton<ICSharpHelper, CSharpHelper>()
                .AddSingleton<AnnotationCodeGeneratorDependencies>()
                .AddSingleton<IAnnotationCodeGenerator, AnnotationCodeGenerator>()
                .AddSingleton<CSharpMigrationOperationGeneratorDependencies>()
                .AddSingleton<ICSharpMigrationOperationGenerator, CSharpMigrationOperationGenerator>()
                .AddSingleton<CSharpSnapshotGeneratorDependencies>()
                .AddSingleton<ICSharpSnapshotGenerator, CSharpSnapshotGenerator>()
                .AddSingleton<CSharpMigrationsGeneratorDependencies>()
                .AddSingleton<IMigrationsCodeGenerator, CSharpMigrationsGenerator>()
                .AddSingleton<MigrationsScaffolderDependencies>()
                .AddSingleton<MigrationsScaffolder>()
                .AddSingleton<IRegisteredServices, RegisteredServices>()
                .AddSingleton<IPropertyParameterBindingFactory, PropertyParameterBindingFactory>()
                .AddSingleton<IParameterBindingFactories, ParameterBindingFactories>()
                .AddSingleton<IConstructorBindingFactory, ConstructorBindingFactory>()
                .AddSingleton<RuntimeModelDependencies>()
                .AddSingleton<IMemberClassifier, MemberClassifier>()
                .AddSingleton<ModelValidatorDependencies>()
                .AddSingleton<IModelValidator, ModelValidator>()
                .AddSingleton<ModelRuntimeInitializerDependencies>()
                .AddSingleton<IModelRuntimeInitializer, ModelRuntimeInitializer>()
                .AddSingleton<ISnapshotModelProcessor, SnapshotModelProcessor>()
                .AddSingleton<MigrationBuilder>()
                .AddSingleton<IMigrationsCodeGeneratorSelector, MigrationsCodeGeneratorSelector>()
                .AddSingleton(ctxInstance.GetService<IHistoryRepository>())
                .AddSingleton(ctxInstance.GetService<IMigrationsIdGenerator>())
                .AddSingleton(ctxInstance.GetService<IMigrationsModelDiffer>())
                .AddSingleton(ctxInstance.GetService<IMigrationsAssembly>())
                .AddSingleton(ctxInstance.GetService<IDesignTimeModel>().Model)
                .AddSingleton(ctxInstance.GetService<ICurrentDbContext>())
                .AddSingleton(ctxInstance.GetService<IDatabaseProvider>())
                .AddSingleton(ctxInstance.GetService<IRelationalTypeMappingSource>())
                .AddSingleton(ctxInstance.GetService<IMigrator>());
            
var serviceProvider = designTimeServices.BuildServiceProvider();
            
string migrationName = GenerateMigrationName();

var scaffolder = serviceProvider.GetRequiredService<MigrationsScaffolder>();
var migration = scaffolder.ScaffoldMigration(migrationName, GetRootNamespace());

// 文件写入逻辑在此处

测试用DbContext实现

public class DevelopmentContext : DbContext
{
    public static string? MigrationAssembly { get; set; }
    
    public DevelopmentContext()
    {
        var folder = Environment.SpecialFolder.LocalApplicationData;
        var path = Environment.GetFolderPath(folder);
        DbPath = Path.Join(path, "development1.db");
    }
    
    public string DbPath { get; }
    
    public DbSet<Foo> Foos { get; }

    public DbSet<Bar> Bars { get; }
    
    protected override void OnConfiguring(DbContextOptionsBuilder options)
    {
        options.UseSqlite($"Data Source={DbPath}", a =>
        {
            if (MigrationAssembly != null)
            {
                a.MigrationsAssembly(MigrationAssembly);
            }
        });
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 16:20:42