dotnet / efcore

EF Core is a modern object-database mapper for .NET. It supports LINQ queries, change tracking, updates, and schema migrations.
https://docs.microsoft.com/ef/
MIT License
13.76k stars 3.18k forks source link

Migration issue with multiple nested "OwnsOne" after upgrading to v.2.2.2 #14994

Closed ASBrattsev closed 2 years ago

ASBrattsev commented 5 years ago

I get error message when I try to update the database after generating a migration. Before upgrading to 2.2.2 - it works fine.

Exception message: System.InvalidOperationException: The entity type 'EFError1.Models.SubAddress' cannot be added to the model because a weak entity type with the same name already exists.
Stack trace:System.InvalidOperationException: The entity type 'EFError1.Models.SubAddress' cannot be added to the model because a weak entity type with the same name already exists.
   at Microsoft.EntityFrameworkCore.Metadata.Internal.Model.AddEntityType(EntityType entityType)
   at Microsoft.EntityFrameworkCore.Metadata.Internal.Model.AddEntityType(String name, ConfigurationSource configurationSource)
   at Microsoft.EntityFrameworkCore.Metadata.Internal.InternalModelBuilder.Entity(TypeIdentity& type, ConfigurationSource configurationSource, Boolean allowOwned, Boolean throwOnQuery)
   at Microsoft.EntityFrameworkCore.Metadata.Internal.InternalModelBuilder.Entity(String name, ConfigurationSource configurationSource, Boolean allowOwned, Boolean throwOnQuery)
   at Microsoft.EntityFrameworkCore.Metadata.Builders.ReferenceOwnershipBuilder.FindRelatedEntityType(String relatedTypeName, String navigationName)
   at Microsoft.EntityFrameworkCore.Metadata.Builders.ReferenceOwnershipBuilder.HasOne(String relatedTypeName, String navigationName)
   at EFError1.Migrations.Initial.<>c.<BuildTargetModel>b__2_7(ReferenceOwnershipBuilder b3) in D:\SandBox\EFIssues\EFError1\EFError1\Migrations\20190312102225_Initial.Designer.cs:line 128
   at Microsoft.EntityFrameworkCore.Metadata.Builders.ReferenceOwnershipBuilder.OwnsOne(String ownedTypeName, String navigationName, Action`1 buildAction)
   at EFError1.Migrations.Initial.<>c.<BuildTargetModel>b__2_6(ReferenceOwnershipBuilder b2) in D:\SandBox\EFIssues\EFError1\EFError1\Migrations\20190312102225_Initial.Designer.cs:line 118
   at Microsoft.EntityFrameworkCore.Metadata.Builders.ReferenceOwnershipBuilder.OwnsOne(String ownedTypeName, String navigationName, Action`1 buildAction)
   at EFError1.Migrations.Initial.<>c.<BuildTargetModel>b__2_3(ReferenceOwnershipBuilder b1) in D:\SandBox\EFIssues\EFError1\EFError1\Migrations\20190312102225_Initial.Designer.cs:line 101
   at Microsoft.EntityFrameworkCore.Metadata.Builders.EntityTypeBuilder.OwnsOne(String ownedTypeName, String navigationName, Action`1 buildAction)
   at EFError1.Migrations.Initial.<>c.<BuildTargetModel>b__2_1(EntityTypeBuilder b) in D:\SandBox\EFIssues\EFError1\EFError1\Migrations\20190312102225_Initial.Designer.cs:line 86
   at Microsoft.EntityFrameworkCore.ModelBuilder.Entity(String name, Action`1 buildAction)
   at EFError1.Migrations.Initial.BuildTargetModel(ModelBuilder modelBuilder) in D:\SandBox\EFIssues\EFError1\EFError1\Migrations\20190312102225_Initial.Designer.cs:line 34
   at Microsoft.EntityFrameworkCore.Migrations.Migration.<.ctor>b__4_0()
   at Microsoft.EntityFrameworkCore.Internal.LazyRef`1.get_Value()
   at Microsoft.EntityFrameworkCore.Migrations.Migration.get_TargetModel()
   at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.GenerateUpSql(Migration migration)
   at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.<>c__DisplayClass13_2.<GetMigrationCommandLists>b__2()
   at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.Migrate(String targetMigration)
   at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.UpdateDatabase(String targetMigration, String contextType)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabase.<>c__DisplayClass0_1.<.ctor>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
The entity type 'EFError1.Models.SubAddress' cannot be added to the model because a weak entity type with the same name already exists.

Steps to reproduce

For reproduce this issue create test project, add EF core 2.2.2, and do the migration using the classes described below

Partial code listings:

public class Root
    {
        public int Id { get; set; }
        public MainAddress Address1 { get; set; }
        public MainAddress Address2 { get; set; }
    }

public class MainAddress
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public  SubAddress SubAddress { get; set; }
    }

public class SubAddress
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Number { get; set; }
    public SubSubAddress SubSubAddress { get; set; }
}

public class SubSubAddress
{
    public int Id { get; set; }
    public string Text { get; set; }
}

public class RootConfig : IEntityTypeConfiguration<Root>
    {
        public void Configure(EntityTypeBuilder<Root> builder)
        {
            builder.ToTable("Roots");

            builder.HasKey(it => it.Id);

            builder.OwnsOne(root => root.Address1, address =>
            {
                address.OwnsOne(a => a.SubAddress, subAddress =>
                {
                    subAddress.OwnsOne(it => it.SubSubAddress);
                });
            });

            builder.OwnsOne(root => root.Address2, address =>
            {
                address.OwnsOne(a => a.SubAddress, subAddress =>
                    {
                        subAddress.OwnsOne(it => it.SubSubAddress);
                    });
            });
        }
    }

public class TestContext : DbContext
    {
        public TestContext(DbContextOptions<TestContext> context) : base(context)
        {

        }

        public DbSet<Root> Roots { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.ApplyConfiguration(new RootConfig());
        }
    }

Further technical details

EF Core version: 2.2.2 Database Provider: Npgsql.EntityFrameworkCore.PostgreSQL 2.2.0 Operating system: Windows 10 IDE: Rider 2018.3

ajcvickers commented 5 years ago

@ASBrattsev What version are you upgrading from?

ASBrattsev commented 5 years ago

I'm upgrading from 2.1.8 to 2.2.2

ASBrattsev commented 5 years ago

The problem has a temporary solution, but I don't like it. I changed the example a bit. It is necessary to comment out the first mentions of a triple attachment of a double "OwnsOne", as on the picture, and then everything works. (sorry if not clearly written, I don't know how to write it in my native language, not that English =) )

image

AndriySvyryd commented 5 years ago

Duplicate of #18183