【问题标题】:How to dealing with multy source Database using DbContext如何使用 DbContext 处理多源数据库
【发布时间】:2022-01-03 13:41:54
【问题描述】:

我使用干净的拱形步骤来创建项目, 但问题是我需要将三个以上的聚合放在引用数据库中。

我尝试对每个聚合使用 DbContext,如下所示:

public class AppDbContext : DbContext
{
  private readonly IMediator? _mediator;

  public AppDbContext(DbContextOptions<AppDbContext> options, IMediator? mediator)
      : base(options)
  {
    _mediator = mediator;
  }
.
.
.
public class AnalyzeDbContext : DbContext
{
  private readonly IMediator? _mediator;

  public AnalyzeDbContext(DbContextOptions<AnalyzeDbContext> options, IMediator? mediator)
      : base(options)
  {
    _mediator = mediator;
  }
.
.
.
public class ProviderMgrDbContext : DbContext
{
  private readonly IMediator? _mediator;


  public ProviderMgrDbContext(DbContextOptions<ProviderMgrDbContext> options, IMediator? mediator)
      : base(options)
  {
    _mediator = mediator;
  }

然后我像这样发送每个 DbContext 的连接字符串:

//#Update 1
 public static void AppDbContext(this IServiceCollection services, string connectionString) =>
   services.AddDbContext<AppDbContext>(options => options.UseMySQL(connectionString));

 public static void ProviderMgrDbContext(this IServiceCollection services, string connectionString) =>
   services.AddDbContext<ProviderMgrDbContext>(options => options.UseMySQL(connectionString));

  public static void AnalyzeDbContext(this IServiceCollection services, string connectionString) =>
   services.AddDbContext<AnalyzeDbContext>(options => options.UseMySQL(connectionString));

//#After
public static void AppDbContext(this IServiceCollection services, string connectionString) =>
   services.AddDbContext<AppDbContext>(options => options.UseMySql(connectionString, new MySqlServerVersion(new Version(8, 0, 27))));

 public static void ProviderMgrDbContext(this IServiceCollection services, string connectionString) =>
   services.AddDbContext<ProviderMgrDbContext>(options => options.UseMySql(connectionString, new MySqlServerVersion(new Version(8, 0, 27))));
  
  public static void AnalyzeDbContext(this IServiceCollection services, string connectionString) =>
   services.AddDbContext<AnalyzeDbContext>(options => options.UseMySql(connectionString, new MySqlServerVersion(new Version(8, 0, 27))));
.
.
.

但是当我尝试迁移它们时,它会显示如下豁免错误:

PM> Add-Migration init_1 -context AppDbContext
Build started...
Build succeeded.
Autofac.Core.DependencyResolutionException: An exception was thrown while activating WetaPayment.Infrastructure.Data.DataContext.AppDbContext.
 ---> Autofac.Core.DependencyResolutionException: An exception was thrown while invoking the constructor 'Void .ctor(Microsoft.EntityFrameworkCore.DbContextOptions`1[WetaPayment.Infrastructure.Data.DataContext.AppDbContext], MediatR.IMediator)' on type 'AppDbContext'.
 ---> System.TypeLoadException: Method 'AppendIdentityWhereCondition' in type 'MySql.EntityFrameworkCore.MySQLUpdateSqlGenerator' from assembly 'MySql.EntityFrameworkCore, Version=5.0.8.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d' does not have an implementation.

最后我修复了与 net6.0 不兼容的更改 MySql.EntityFrameworkCore 包的部分问题,因此我使用了 Pomelo.EntityFrameworkCore.MySql 并且它成功运行。

但是我还有另一个问题是我的所有聚合在所有上下文中都秃顶了,我需要每个 DbContext 只构建他的聚合,那么如何解决它?

【问题讨论】:

  • 10 次中有 9 次我在 EF Core 中看到 TypeLoadException,这是因为我使用的是不兼容版本的 EF Core 包,请确保您在所有项目中对 EF Core 的所有引用都引用相同的版本
  • 亲爱的 MindSwipe 我检查了我的 EF 版本,都是最新版本,我使用的是 net6.0。
  • MindSwipe uoy 是对的,最后我发现我的MySql.EntityFrameworkCore backage 与 net6.0 不兼容,所以我使用了Pomelo.EntityFrameworkCore.MySql,它成功了。
  • 现在我有另一个问题,我的所有聚合在所有上下文中都秃顶了,我需要每个 DbContext 只构建他的聚合。

标签: c# entity-framework asp.net-core domain-driven-design ardalis-cleanarchitecture


【解决方案1】:

每个DbContext 可以配置自己的实体

假设我们有 10 个实体代表 3 个 DbContext,我们可以将它们分成 ADbContext 的 2 个实体,BDbContext 的 5 个实体和 CDbContext 的 3 个实体。明智地管理它们之间的FK 之类的配置,否则就会变得混乱。下面是如何做到这一点,使用流畅的 API

public class MyAppDbContext : DbContext
{
    public DbSet<OurEntity> OurEntity { get; set; }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        builder.Entity<OurEntity>(builder => 
       {
            // Our implementation goes here...
       });
    }
}

这样,我们只配置和注册每个DbContext对应的实体。

我们需要将每个 DbContext 分别注册到任何类型的 DI

为每个DbContext组织迁移操作

我通常将它们组织在这样的文件夹中:

Data/Migrations/ContextA
Data/Migrations/ContextB
Data/Migrations/ContextC

每个上下文都有自己的迁移和快照。

在使用 EF 迁移工具时,通过指定单独的 DbContext 来执行此操作

add-migration add [MigrationName] -context [DbContextName] -o [Path to desire place to store migration]

然后分别应用它们

update-database -context [DbContextName]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-14
    • 1970-01-01
    • 2014-06-26
    • 2010-12-12
    • 2019-05-04
    • 2013-08-18
    相关资源
    最近更新 更多