EF Core DbContext 在数据库之间迁移数据时总是使用错误的连接字符串

问题描述 投票:0回答:1

我在使用 Entity Framework Core 的 .NET Core 项目中面临依赖注入问题。我有多个 DbContext(

SourceDbContext
TargetDbContext
),都继承自
ApplicationDbContext
。目标是使用两个不同的连接字符串将数据从我的开发数据库(源)迁移到我的 QA 数据库(目标)。

但是,当我尝试打印

SourceDbContext
的连接字符串时,它始终使用
TargetDbContext
(
DefaultConnection
) 的连接字符串,而不是使用
PreviousConnection

这是我的代码 -

Program.cs
:

builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection"))
           .AddInterceptors(new PerformanceInterceptor()));

builder.Services.AddDbContext<SourceDbContext>(options =>
    options.UseNpgsql(builder.Configuration.GetConnectionString("PreviousConnection")));

builder.Services.AddDbContext<TargetDbContext>(options =>
    options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection")));

DataMigrationService

public class DataMigrationService
{
    private readonly SourceDbContext _sourceContext;
    private readonly TargetDbContext _targetContext;

    public DataMigrationService(SourceDbContext sourceContext, TargetDbContext targetContext)
    {
        _sourceContext = sourceContext;
        _targetContext = targetContext;
    }

    public async Task MigrateTableDataAsync()
    {
        Console.WriteLine($"Source DB Connection String: {_sourceContext.Database.GetConnectionString()}");
        Console.WriteLine($"Target DB Connection String: {_targetContext.Database.GetConnectionString()}");

        // Fetch data from source DB
        var sourceWhiteLists = await _sourceContext.EmailDomainWhiteLists.ToListAsync();
        
        // Fetch data from target DB
        var targetWhiteLists = await _targetContext.EmailDomainWhiteLists.ToListAsync();
        
        foreach (var wl in sourceWhiteLists)
        {
            var targetWL = await _targetContext.EmailDomainWhiteLists.FirstOrDefaultAsync(x => x.Value == wl.Value);
            if (targetWL == null)
            {
                _targetContext.EmailDomainWhiteLists.Add(wl);
            }
        }

        await _targetContext.SaveChangesAsync();
        Console.WriteLine("Migration completed.");
    }
}

SourceDbContext

public class SourceDbContext : ApplicationDbContext
{
    public SourceDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }
}

Program.cs
中,我使用不同的连接字符串注入
SourceDbContext
TargetDbContext
。然而,
SourceDbContext
似乎继承了
ApplicationDbContext
的连接字符串,它始终指向QA数据库。

如何确保

SourceDbContext
使用自己的连接字符串 (
PreviousConnection
),而不是从
ApplicationDbContext
继承默认连接字符串?

提前致谢!

附加信息:

  • 我尝试使用 Console.WriteLine 检查连接字符串,很明显
    SourceDbContext
    仍在使用
    DefaultConnection
  • 我需要
    SourceDbContext
    TargetDbContext
    才能将各自的连接字符串用于 DEV 和 QA 环境

任何帮助将不胜感激!

c# asp.net-core entity-framework-core
1个回答
0
投票

问题可能源于此构造函数:

public SourceDbContext(DbContextOptions<ApplicationDbContext> options)
    : base(options)

SourceDbContext 的构造函数应该期望

DbContextOptions<SourceDbContext>
,但这样做时,您将无法扩展基础 ApplicationDbContext,因为它需要 ApplicationDbContext 的选项。传递的 DbContextOptions 很可能是从 ApplicationDbContext 的默认注册解析的,而不是 SourceDbContext。

如果您想为源和目标的应用程序 DbContext 定义基类以使用不同的选项进行扩展,那么一种选择是使基 ApplicationDbContext 通用:

public abstract class ApplicationDbContext<T> : DbContext where T : ApplicationDbContext<T>
{
    public ApplicationDbContext(DbContextOptions<T> options) 
        : base (options) { }

    // ...
}

public class SourceDbContext : ApplicationDbContext<SourceDbContext>
{
    public SourceDbContext(DbContextOptions<SourceDbContext> options)
        : base(options)
    { }
}

...以及 TargetDbContext。

这应该确保您的源/目标 DbContext 可以分别解析它们的 DbOptions 并通过基本 ApplicationDbContext 向下传递它们。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.