Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent creating migrations and applying them for specified dbContext in Entity Framework Core 6?

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");
    }
}
like image 235
Mikolaj Avatar asked Sep 08 '25 07:09

Mikolaj


1 Answers

You can exclude from migrations:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
  modelBuilder.Entity<ApplicationUser>().ToTable("ApplicationUsers", t => t.ExcludeFromMigrations());
}
like image 180
ErikEJ Avatar answered Sep 10 '25 04:09

ErikEJ