Skip to content

Bug: ToView + Navigation property + HasPrincipalKey breaks migrations (with root cause identification) #21165

@ntziolis

Description

@ntziolis

When having the following scenario configured in the model:

  • EntityA is marked as readonly by using ToView()
  • EntityA has a navigation property to EntityB, using Alternate Key on EntityB

It results in:

  • Every subsequent migration created will now always contain the creation of alternate key on EntityB.
  • The alternate key is not dropped inside the Up method but only created
  • Which makes every execution of ef migrations update fail moving forward

To be clear this happens not just the first time after adding, but every time we create a new migration from now on.

Please see the Identifying the root cause section at the end as I think I have pinpointed the problem.

Business Scenario:

  • New application with normal entities
  • Legacy System (all tables are treated as readonly via toView as recommened in the docs)
  • Both are contained in the same database
  • To connect both worlds we use navigation properties

Steps to reproduce

  • Create new project with a DbContext
  • Add Entities and model builder code to DbContext as seen below
  • Create initial migration
  • Create additional migration right afterwards
  • In second migration the alternate key on Entity B is created again without dropping (same is true for all subsequently created migrations)
// the table comes from a legacy system, we cannot change it in any way
public class EntityA{
	public int Id { get; set; }
		
	public int MyNavigationPropertyId { get; set; }
	public EntityB MyNavigationProperty { get; set; }
}

public class EntityB{
	public int Id { get; set; }
	public int AlternateKeyOnEntityB { get; set; }
}

modelBuilder.Entity<EntityA>(entity =>
{
	entity.ToView("EntityA");
		
	entity.HasOne(d => d.MyNavigationProperty)
	     .WithMany()                    
	     .HasPrincipalKey(d => d.AlternateKeyOnEntityB);
});

Identifying the root cause:

  • When looking at the snapshot file the alternate key is not defined here
  • When manually adding it and then creating a migration
    • the Up/Down methods are empty as expected
    • but the newly generated snapshot will again NOT contain the alternate key definition
  • Based on the above behaviour + Looking at the code I think I could pinpoint the issue
    • When generating a new snapshot the IsIgnoredByMigrations extension method is called
    • This method returns true when the entity is a view (besides other things)
    • Since the relation + alternate key are defined as part of the entity that is marked ToView
    • The entity (and all operations attached to it are filtered out
  • Also: While the sample is one to many, the same error appears in one to one scenario

Further technical details

EF Core version: 3.1.3
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: .NET Core 3.1
Operating system: Windows
IDE: Visual Studio 2019 16.3, but doesn't matter as migrations were crated via dotnet ef cli

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions