如何防止在 Entity Framework Core 6 中创建迁移并将其应用于指定的 dbContext?
我在读取和写入端使用两个数据库上下文,指向相同的数据库架构。
ReadDbContext 和 WriteDbContext 分别定义了自己的读和写模型。
由于这两种上下文配置中的关系、表名以及最后的数据库都是相同的,因此只有其中之一可以构建数据库。
有没有办法禁用为指定数据库上下文应用创建的迁移的能力?更进一步,是否有可能禁止迁移创建?
我尝试将 Database.SetInitializer
添加到 DbContext 构造函数,但这似乎在 EF Core 6 中不起作用。
为了更好地理解,您可以查看下面的代码。
ReadDbContext
internal sealed class ReadDbContext : DbContext
{
public DbSet<UserReadModel> Users => Set<UserReadModel>();
public DbSet<RoleReadModel> Roles => Set<RoleReadModel>();
public DbSet<PermissionReadModel> Permissions => Set<PermissionReadModel>();
public ReadDbContext(DbContextOptions<ReadDbContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.HasDefaultSchema("user-manager");
var configuration = new ReadConfiguration();
modelBuilder.ApplyConfiguration<UserReadModel>(configuration);
modelBuilder.ApplyConfiguration<RoleReadModel>(configuration);
modelBuilder.ApplyConfiguration<PermissionReadModel>(configuration);
}
}
WriteDbContext
internal sealed class WriteDbContext : DbContext
{
public DbSet<User> Users => Set<User>();
public DbSet<Role> Roles => Set<Role>();
public DbSet<Permission> Permissions => Set<Permission>();
public WriteDbContext(DbContextOptions<WriteDbContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.HasDefaultSchema("user-manager");
var configuration = new WriteConfiguration();
modelBuilder.ApplyConfiguration<User>(configuration);
modelBuilder.ApplyConfiguration<Role>(configuration);
modelBuilder.ApplyConfiguration<Permission>(configuration);
}
}
ReadConfiguration
internal sealed class ReadConfiguration : IEntityTypeConfiguration<UserReadModel>, IEntityTypeConfiguration<RoleReadModel>,
IEntityTypeConfiguration<PermissionReadModel>
{
private readonly ValueConverter<UserNameReadModel, string> _userNameConverter = new(un => un.ToString(), un => new UserNameReadModel(un));
public void Configure(EntityTypeBuilder<UserReadModel> builder)
{
builder.ToTable("Users");
builder.HasKey(u => u.Id);
builder
.HasMany(u => u.Roles)
.WithMany(r => r.Users)
.UsingEntity("UsersRoles");
builder
.Property(u => u.Name)
.HasConversion(_userNameConverter!);
}
public void Configure(EntityTypeBuilder<RoleReadModel> builder)
{
builder.ToTable("Roles");
builder.HasKey(r => r.Id);
builder
.HasMany(r => r.Permissions)
.WithMany(p => p.Roles)
.UsingEntity("RolesPermissions");
}
public void Configure(EntityTypeBuilder<PermissionReadModel> builder)
{
builder.ToTable("Permissions");
builder.HasKey(p => p.Id);
}
}
WriteConfiguration
internal sealed class WriteConfiguration : IEntityTypeConfiguration<User>, IEntityTypeConfiguration<Role>,
IEntityTypeConfiguration<Permission>
{
private readonly ValueConverter<UserId, Guid> _userIdConverter = new(u => u.Value, u => u);
private readonly ValueConverter<RoleId, Guid> _roleIdConverter = new(r => r.Value, r => r);
private readonly ValueConverter<UserName, string> _userNameConverter = new(un => un.ToString(), un => UserName.Create(un));
private readonly ValueConverter<RoleName, string> _roleNameConverter = new(rn => rn.ToString(), rn => RoleName.Create(rn));
private readonly ValueConverter<Email, string> _emailConverter = new(e => e.ToString(), e => Email.Create(e));
private readonly ValueConverter<Password, string> _passwordConverter = new(p => p.ToString(), p => Password.Create(p));
public void Configure(EntityTypeBuilder<User> builder)
{
builder.ToTable("Users");
builder.HasKey(u => u.Id);
builder
.Property(r => r.Id)
.HasConversion(_userIdConverter);
builder
.Property(typeof(UserName), "_name")
.HasConversion(_userNameConverter)
.HasColumnName("Name");
builder
.Property(typeof(Email), "_email")
.HasConversion(_emailConverter)
.HasColumnName(nameof(Email));
builder
.Property(typeof(Password), "_password")
.HasConversion(_passwordConverter)
.HasColumnName(nameof(Password));
builder
.HasMany(typeof(Role), "_roles")
.WithMany("_users")
.UsingEntity("UsersRoles");
}
public void Configure(EntityTypeBuilder<Role> builder)
{
builder.ToTable("Roles");
builder.HasKey(r => r.Id);
builder
.Property(r => r.Id)
.HasConversion(_roleIdConverter);
builder
.Property(typeof(RoleName), "_name")
.HasConversion(_roleNameConverter)
.HasColumnName("Name");
builder.HasMany(typeof(Permission), "_permissions");
}
public void Configure(EntityTypeBuilder<Permission> builder)
{
builder.ToTable("Permissions");
builder.Property<Guid>("Id");
builder.Property<string>("Name");
}
}
I'm using two db contexts for read and write side, poinitng to the same db schema.
ReadDbContext and WriteDbContext have their own read and write models defined respectively.
Since the relations, table names and finally the database are the same in both of these contexts configuration, only the one of them can scaffold the database.
Is there any way to disable the ability of applying created migrations for specified db conext? Going further, is there a possibility to even disallow the migrations creating?
I tried to add Database.SetInitializer<TContext>(null)
to DbContext constructor, but that doesn't seem to work in EF Core 6.
For better understanding you can checkout the code below.
ReadDbContext
internal sealed class ReadDbContext : DbContext
{
public DbSet<UserReadModel> Users => Set<UserReadModel>();
public DbSet<RoleReadModel> Roles => Set<RoleReadModel>();
public DbSet<PermissionReadModel> Permissions => Set<PermissionReadModel>();
public ReadDbContext(DbContextOptions<ReadDbContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.HasDefaultSchema("user-manager");
var configuration = new ReadConfiguration();
modelBuilder.ApplyConfiguration<UserReadModel>(configuration);
modelBuilder.ApplyConfiguration<RoleReadModel>(configuration);
modelBuilder.ApplyConfiguration<PermissionReadModel>(configuration);
}
}
WriteDbContext
internal sealed class WriteDbContext : DbContext
{
public DbSet<User> Users => Set<User>();
public DbSet<Role> Roles => Set<Role>();
public DbSet<Permission> Permissions => Set<Permission>();
public WriteDbContext(DbContextOptions<WriteDbContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.HasDefaultSchema("user-manager");
var configuration = new WriteConfiguration();
modelBuilder.ApplyConfiguration<User>(configuration);
modelBuilder.ApplyConfiguration<Role>(configuration);
modelBuilder.ApplyConfiguration<Permission>(configuration);
}
}
ReadConfiguration
internal sealed class ReadConfiguration : IEntityTypeConfiguration<UserReadModel>, IEntityTypeConfiguration<RoleReadModel>,
IEntityTypeConfiguration<PermissionReadModel>
{
private readonly ValueConverter<UserNameReadModel, string> _userNameConverter = new(un => un.ToString(), un => new UserNameReadModel(un));
public void Configure(EntityTypeBuilder<UserReadModel> builder)
{
builder.ToTable("Users");
builder.HasKey(u => u.Id);
builder
.HasMany(u => u.Roles)
.WithMany(r => r.Users)
.UsingEntity("UsersRoles");
builder
.Property(u => u.Name)
.HasConversion(_userNameConverter!);
}
public void Configure(EntityTypeBuilder<RoleReadModel> builder)
{
builder.ToTable("Roles");
builder.HasKey(r => r.Id);
builder
.HasMany(r => r.Permissions)
.WithMany(p => p.Roles)
.UsingEntity("RolesPermissions");
}
public void Configure(EntityTypeBuilder<PermissionReadModel> builder)
{
builder.ToTable("Permissions");
builder.HasKey(p => p.Id);
}
}
WriteConfiguration
internal sealed class WriteConfiguration : IEntityTypeConfiguration<User>, IEntityTypeConfiguration<Role>,
IEntityTypeConfiguration<Permission>
{
private readonly ValueConverter<UserId, Guid> _userIdConverter = new(u => u.Value, u => u);
private readonly ValueConverter<RoleId, Guid> _roleIdConverter = new(r => r.Value, r => r);
private readonly ValueConverter<UserName, string> _userNameConverter = new(un => un.ToString(), un => UserName.Create(un));
private readonly ValueConverter<RoleName, string> _roleNameConverter = new(rn => rn.ToString(), rn => RoleName.Create(rn));
private readonly ValueConverter<Email, string> _emailConverter = new(e => e.ToString(), e => Email.Create(e));
private readonly ValueConverter<Password, string> _passwordConverter = new(p => p.ToString(), p => Password.Create(p));
public void Configure(EntityTypeBuilder<User> builder)
{
builder.ToTable("Users");
builder.HasKey(u => u.Id);
builder
.Property(r => r.Id)
.HasConversion(_userIdConverter);
builder
.Property(typeof(UserName), "_name")
.HasConversion(_userNameConverter)
.HasColumnName("Name");
builder
.Property(typeof(Email), "_email")
.HasConversion(_emailConverter)
.HasColumnName(nameof(Email));
builder
.Property(typeof(Password), "_password")
.HasConversion(_passwordConverter)
.HasColumnName(nameof(Password));
builder
.HasMany(typeof(Role), "_roles")
.WithMany("_users")
.UsingEntity("UsersRoles");
}
public void Configure(EntityTypeBuilder<Role> builder)
{
builder.ToTable("Roles");
builder.HasKey(r => r.Id);
builder
.Property(r => r.Id)
.HasConversion(_roleIdConverter);
builder
.Property(typeof(RoleName), "_name")
.HasConversion(_roleNameConverter)
.HasColumnName("Name");
builder.HasMany(typeof(Permission), "_permissions");
}
public void Configure(EntityTypeBuilder<Permission> builder)
{
builder.ToTable("Permissions");
builder.Property<Guid>("Id");
builder.Property<string>("Name");
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以从迁移中排除:
You can exclude from migrations: