Open Closed

Duplicate AbpBlobContainers and AbpBlobs tables generated in module migration when using Database Blob Provider #10521


User avatar
0
prince-mantle created

I am using ABP Framework (ABP Suite) in a Monolithic Modular architecture (DDD model).

In one of my entities, I used a File type property to store a file as a blob. For this purpose, I configured the database blob provider inside my module.

Configuration

Inside XXXXEntityFrameworkCoreModule : AbpModule, I added the following configuration:

Configure<AbpBlobStoringOptions>(options =>
{
    options.Containers.ConfigureDefault(container =>
    {
        container.UseDatabase();
    });
});

The project compiles successfully.

Migration Generation

I prefer to store module-specific migrations within the module itself, so I generated the migration using the following command:

dotnet ef migrations add Add_PSPluginVersion \
  --context ConnectDbContext \
  --project "$(git rev-parse --show-toplevel)/modules/connect/src/Mantle.Connect.EntityFrameworkCore/" \
  --startup-project "$(git rev-parse --show-toplevel)/src/Mantle.PowerAut0mater.HttpApi.Host/"

Issue

The migration was generated with the following table creation statements:

  • AbpBlobContainers
  • AbpBlobs

However, these tables already exist in the database, so applying the migration results in an error due to duplicate table creation.

Generated migration snippet:

migrationBuilder.CreateTable(
    name: "AbpBlobContainers",
    columns: table => new
    {
        Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
        TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
        Name = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: false),
        ExtraProperties = table.Column<string>(type: "nvarchar(max)", nullable: false),
        ConcurrencyStamp = table.Column<string>(type: "nvarchar(40)", maxLength: 40, nullable: false)
    },
    constraints: table =>
    {
        table.PrimaryKey("PK_AbpBlobContainers", x => x.Id);
    });

migrationBuilder.CreateTable(
    name: "AbpBlobs",
    columns: table => new
    {
        Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
        ContainerId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
        TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
        Name = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false),
        Content = table.Column<byte[]>(type: "varbinary(max)", maxLength: 2147483647, nullable: true),
        ExtraProperties = table.Column<string>(type: "nvarchar(max)", nullable: false),
        ConcurrencyStamp = table.Column<string>(type: "nvarchar(40)", maxLength: 40, nullable: false)
    },
    constraints: table =>
    {
        table.PrimaryKey("PK_AbpBlobs", x => x.Id);
        table.ForeignKey(
            name: "FK_AbpBlobs_AbpBlobContainers_ContainerId",
            column: x => x.ContainerId,
            principalTable: "AbpBlobContainers",
            principalColumn: "Id",
            onDelete: ReferentialAction.Cascade);
    });

Problem

These tables are already available in the database, likely created by the main application migration. However, when generating migrations inside the module, the system attempts to recreate them, causing migration conflicts.

Question

What is the recommended approach when using the Database Blob Provider in a modular monolithic architecture where:

  • Each module maintains its own migrations
  • Shared ABP infrastructure tables (like AbpBlobs and AbpBlobContainers) already exist in the main database

How can I prevent the migration generator from recreating these existing ABP blob tables?

Project Structure

modules/
  connect/
    src/
      Mantle.Connect.EntityFrameworkCore
      Mantle.Connect.Domain
      Mantle.Connect.Application
      ...

src/
  Mantle.PowerAut0mater.EntityFrameworkCore
  Mantle.PowerAut0mater.HttpApi.Host
  ...


3 Answer(s)
  • User Avatar
    0
    AI-Bot created
    Support Team ABP Agent
    • In ABP, the Database BLOB Provider tables (AbpBlobContainers, AbpBlobs) are added to the EF Core model only if the DbContext includes the BLOB-Storing model configuration (i.e., the builder.ConfigureBlobStoring() mappings are part of that DbContext’s OnModelCreating).

    • When you run dotnet ef migrations add ... --context ConnectDbContext, EF compares:

      1. the current model of ConnectDbContext and
      2. the last model snapshot for ConnectDbContext

      If your ConnectDbContext currently includes ConfigureBlobStoring() but the snapshot (or previous module migrations history) didn’t, EF thinks these tables are new for that context and generates CreateTable for them—even if they already exist in the physical database due to the main app’s migration history.

    Recommended approach (modular monolith + per-module migrations)

    1. Pick a single “owner” migration DbContext for shared ABP infrastructure tables, and generate/apply those tables only from that owner.

      • For BLOB database provider tables, that means: only one migrations DbContext in the solution should include builder.ConfigureBlobStoring().
      • Typically, this is your main application MigrationsDbContext (the one that already created them in the “main application migration”).
    2. Do NOT include Blob-Storing model mappings in module-specific DbContexts that maintain their own migrations, unless that module is intended to “own” those tables in its own migrations history.

      • In practice: remove/avoid calling builder.ConfigureBlobStoring() in ConnectDbContext (or in that module’s migrations DbContext).
      • You can still use blob storing (runtime configuration like container.UseDatabase() is fine), but schema creation for AbpBlobs/AbpBlobContainers should come from the single owner migrations set.
    3. If you already generated a module migration that contains these CreateTable calls:

      • Delete that migration (and snapshot changes) and regenerate after ensuring the module DbContext doesn’t include the blob-storing mappings, or
      • Keep the migration but manually remove the CreateTable for AbpBlobContainers / AbpBlobs (and corresponding indexes/FKs) so the module migration only contains module-owned schema changes.

    This keeps each module’s migrations independent while preventing “shared infrastructure” tables from being created multiple times by different migration histories.

    Sources:

    • https://abp.io/docs/10.1/framework/infrastructure/blob-storing/database
    • https://abp.io/docs/10.1/modules/database-tables

    This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.

  • User Avatar
    0
    prince-mantle created

    I have removed builder.ConfigureBlobStoring() from the module public class ConnectDbContext : AbpDbContext<ConnectDbContext>, IConnectDbContext and every thing worked as expected

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    Great

Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v10.3.0-preview. Updated on March 13, 2026, 12:51
1
ABP Assistant
🔐 You need to be logged in to use the chatbot. Please log in first.