Rachel
Rachel

Reputation: 169

EF Core 5.0 - Do you need to generate a migration when changing a "Defining Query" -mapped entity?

I added an entity class to my EF Core 5.0/MS SQL Server data model that is backed by a defining query (raw SQL query, with no table or view corresponding to it in my database).

When I make changes to it (for example, adding a new column) and then run Add-Migration in Package Manager Console to create a migration step, it generates a migration with empty Up(MigrationBuilder migrationBuilder) and Down(MigrationBuilder migrationBuilder) methods. But the generated [MigrationName].Designer.cs file contains the new column, and the ModelSnapshot for my DbContext gets modified to include the new columns, so something has changed.

My question is, do I need to add a migration each time I make a change to one of these entities in order for my app to function properly? If they're not needed, what is considered better practice when I update the defining query -backed entity:

A. Adding these migrations even though they have blank Up(MigrationBuilder migrationBuilder) and Down(MigrationBuilder migrationBuilder) methods, because the model changed, or

B. Not generating the migration and just having these changes get picked up the next time someone makes a change that actually impacts the underlying database structures?

Code snippets (over-simplified to remove identifying data):

Entity class

public class Thing
{
    public int Id { get; set; }

    public string Name { get; set; }
}

Entity Configuration:

public class ThingTypeConfiguration : IEntityTypeConfiguration<Thing>
{
    public void Configure(EntityTypeBuilder<Thing> builder)
    {
        builder
            .HasNoKey()
            .ToView("Dummy") // This is here to work around an issue with the migrations auto-generating a table for the entity - see https://github.com/dotnet/efcore/issues/19972 
            .ToSqlQuery(
            @"SELECT
                [TableName].[IdColumn] AS Id,
                [TableName].[OtherColumn] AS Name
            FROM 
                [TableName]");
    }
}

DbContext:

public class MyDbContext : DbContext
{
    public MyDbContext()
    {
    }

    public MyDbContext(DbContextOptions<MyDbContext> options)
        : base(options)
    {
    }

    public virtual DbSet<Thing> Things { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        if (!optionsBuilder.IsConfigured)
        {
        }
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.ApplyConfigurationsFromAssembly(typeof(MyDbContext).Assembly);
    }
}

Examples of Migration partial classes that get generated:

Partial class with empty Up/Down methods:

public partial class MyMigration : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
    
    }

    protected override void Down(MigrationBuilder migrationBuilder)
    {

    }
}

Auto-generated __.Designer.cs file (the rest of the class):

[DbContext(typeof(MyDbContext))]
[Migration("20210302175116_MyMigration")]
partial class MyMigration
{
    protected override void BuildTargetModel(ModelBuilder modelBuilder)
    {
#pragma warning disable 612, 618
        modelBuilder
            .HasAnnotation("Relational:MaxIdentifierLength", 128)
            .HasAnnotation("ProductVersion", "5.0.3")
            .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);

        /* Entity configuration logic for all the other entities in my model.. */

        modelBuilder.Entity("MyDataProject.Thing", b =>
            {
                b.Property<string>("Id")
                    .HasColumnType("int");

                b.Property<string>("Name")
                    .HasColumnType("nvarchar(max)");

                b.ToView("Dummy");

                b
                    .HasAnnotation("Relational:SqlQuery", "/* My SQL query */");
            });
#pragma warning restore 612, 618
    }
}

Upvotes: 9

Views: 2679

Answers (1)

bricelam
bricelam

Reputation: 30375

No. If the database schema hasn't changed, you don't need to add a new migration.

Heck, you don't even really need to add a new migration if the new schema is compatible with the old one. For example, removing an optional property would still be compatible.

The *.Designer file is just there to occasionally provide additional information about the model when generating SQL. And, Since the migration doesn't generate SQL, it's entirely unused in this case.

Upvotes: 4

Related Questions