Search code examples
c#entity-framework-coreabp-framework

Upgrading ABP 3.3.1 to 7.0.1 : Handling database migrations for existing applications - It tries to CREATE existing tables


I have just upgraded an existing application from ABP 3.3.1 to 7.0.1

I have resolved all dependency issues, build errors and updates in the code.

Now I am trying to run the DB migrator after creating a new migration as advised in the documentation:

Use Add-Migration "Upgraded_To_Abp_4_1" or a similar command in the Package Manager Console (PMC) to create a new migration (Set the EntityFrameworkCore as the Default project in the PMC and .DbMigrator as the Startup Project in the Solution Explorer, in the Visual Studio).

The issue I am having is that it wants to create new tables that already exist.

So I am getting an exception An unhandled exception of type 'Microsoft.Data.SqlClient.SqlException' occurred in System.Private.CoreLib.dll There is already an object named 'AbpAuditLogs' in the database.

ABP Error

If I look at the migration code I do see that it CREATES a new table. It doesn't ALTER

What is the ABP approach to solve this?

migrationBuilder.CreateTable(
            name: "AbpAuditLogs",
            columns: table => new
            {
                Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
                ApplicationName = table.Column<string>(type: "nvarchar(96)", maxLength: 96, nullable: true),
                BrowserInfo = table.Column<string>(type: "nvarchar(512)", maxLength: 512, nullable: true),
                ClientId = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: true),
                ClientIpAddress = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: true),
                ClientName = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: true),
                Comments = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true),
                ConcurrencyStamp = table.Column<string>(type: "nvarchar(40)", maxLength: 40, nullable: true),
                CorrelationId = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: true),
                Exceptions = table.Column<string>(type: "nvarchar(max)", nullable: true),
                ExecutionDuration = table.Column<int>(type: "int", nullable: false),
                ExecutionTime = table.Column<DateTime>(type: "datetime2", nullable: false),
                ExtraProperties = table.Column<string>(type: "nvarchar(max)", nullable: true),
                HttpMethod = table.Column<string>(type: "nvarchar(16)", maxLength: 16, nullable: true),
                HttpStatusCode = table.Column<int>(type: "int", nullable: true),
                ImpersonatorTenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
                ImpersonatorTenantName = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: true),
                ImpersonatorUserId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
                ImpersonatorUserName = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true),
                TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
                TenantName = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: true),
                Url = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true),
                UserId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
                UserName = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true)
            },
            constraints: table =>
            {
                table.PrimaryKey("PK_AbpAuditLogs", x => x.Id);
            });

Solution

  • Because of time constraints and this being a once-off exercise, I ended up using Redgate Compare (Free trial - feature complete)

    1. Created a new ABP project via CLI with exact same name and CLI options as old one
    2. Ran the migration for the new project, so it creates the DB
    3. Backed up the existing DB (for the old ABP)
    4. Compared the Old ABP DB & New ABP DB
    5. Generated backup INSERT scripts for the AbpUsers table (has breaking schema changes)
    6. DELETE data from the AbpUsers table
    7. Deployed the changes to old DB
    8. Ran the backup INSERT scripts from 5
    9. DONE

    All this in under 2 hours.

    Still open to hear of a better, faster and data-safe way