如何使用 DbContext 处理多源数据库
How to dealing with multy source Database using DbContext
我使用干净的拱形步骤来创建项目,
但问题是我有超过三个集合,我需要将它们放入引用数据库中。
我尝试像这样为每个聚合使用 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 只构建他的聚合,那么如何解决它?
每个DbContext
可以配置自己的实体
假设我们有 3 个 DbContext
的 10 个实体,我们可以将它们分成 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]
我使用干净的拱形步骤来创建项目, 但问题是我有超过三个集合,我需要将它们放入引用数据库中。
我尝试像这样为每个聚合使用 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 只构建他的聚合,那么如何解决它?
每个DbContext
可以配置自己的实体
假设我们有 3 个 DbContext
的 10 个实体,我们可以将它们分成 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]