Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to manage a generated migration that is using a delete class #31630

Closed
juchom opened this issue Sep 5, 2023 · 2 comments
Closed

How to manage a generated migration that is using a delete class #31630

juchom opened this issue Sep 5, 2023 · 2 comments

Comments

@juchom
Copy link

juchom commented Sep 5, 2023

I have a project that has a Contact entity like this

public class Contact
{
    public List<PhoneContact> Phones { get; set; }
}

public class PhoneContact
{
    public string Title { get; set; }
    public string Number { get; set; }
}

internal class ContactConfiguration : IEntityTypeConfiguration<Contact>
{
    public override void Configure(EntityTypeBuilder<Contact> builder)
    {
        {
            builder.Property(p => p.Phones)
                   .HasColumnType("jsonb");
        }
    }
}

The generated migration is doing this

namespace MyApp.Migrations.ApplicationMigrations
{
    public partial class InitialCreate : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.CreateTable(
                name: "Contacts",
                schema: "app",
                columns: table => new
                {
                    Phones = table.Column<List<PhoneContact>>(type: "jsonb", nullable: false)
                }
        }
    }
}

namespace MyApp.Migrations.ApplicationMigrations
{
    [DbContext(typeof(ApplicationMigrationDbContext))]
    partial class ApplicationMigrationDbContextModelSnapshot : ModelSnapshot
    {
        protected override void BuildModel(ModelBuilder modelBuilder)
        {
                    b.Property<List<PhoneContact>>("Phones")
                        .IsRequired()
                        .HasColumnType("jsonb");
        }
    }
}

I want to drop the Phones column from my Contact entity and I want to delete the PhoneContact class that is not used anymore.

The problem is that old migrations are using this class and the project does not want to compile anymore because I deleted it.

What would be the best way to handle this case without destroying all migrations?

Include provider and version information

EF Core version:
Database provider: Npgsql
Target framework: .NET 7.0
Operating system: Windows 11 / WSL 2
IDE: Rider

@juchom
Copy link
Author

juchom commented Sep 5, 2023

What I made right now to bypass this, I moved my class inside the migration class, mark it internal and made the default constructor private:

namespace MyApp.Migrations.ApplicationMigrations
{
    public partial class InitialCreate : Migration
    {
        internal class PhoneContact
        {
            private PhoneContact()
            {
            }

            public string Title { get; set; }
            public string Number { get; set; }
        }

        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.CreateTable(
                name: "Contacts",
                schema: "app",
                columns: table => new
                {
                    Phones = table.Column<List<PhoneContact>>(type: "jsonb", nullable: false)
                }
        }
    }
}

And I changed the snapshot class like this :

namespace MyApp.Migrations.ApplicationMigrations
{
    [DbContext(typeof(ApplicationMigrationDbContext))]
    partial class ApplicationMigrationDbContextModelSnapshot : ModelSnapshot
    {
        protected override void BuildModel(ModelBuilder modelBuilder)
        {
                    // FROM THIS
                    b.Property<List<PhoneContact>>("Phones")
                        .IsRequired()
                        .HasColumnType("jsonb");

                    // TO THIS
                    b.Property<List<InitialCreate.PhoneContact>>("Phones")
                        .IsRequired()
                        .HasColumnType("jsonb");
        }
    }
}

@ajcvickers
Copy link
Contributor

@roji This looks like an Npgsql-specific issue where the collection type is included in the snapshot because it is mapped as a primitive type by PostgreSQL.

@bricelam Can you check that we're not putting user CLR types in migrations for primitive collections (or complex types) when using SQL Server/SQLite?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants