Efcore: The type cannot be marked as owned because a non-owned entity type with the same name already exists

Created on 27 Sep 2019  路  9Comments  路  Source: dotnet/efcore

Upgraded to ef core 3.0 and OwnsMany calls are giving the following error:

image

image

The entity:
image

The valueobject:
image

This was working in the previous ef core version

closed-question customer-reported

All 9 comments

Intentional breaking change as per #9148

@AndriySvyryd - Do you want to add this to breaking changes doc?

@codehunter13 - I could not see where you are configuring UserNotification as regular entity in your code snippets but running the code snippets you posted also does not throw exception for me.
Can you verify that you are hitting what is in #9148? If not can you provide a full repro code which shows the issue?

I have the same error after upgrade
_InvalidOperationException: The type 'OwnedCustomerName' cannot be marked as owned because a non-owned entity type with the same name already exists._

That's my code

 public class CustomerContact
    {
        public CustomerContact()
        {
        }

        public string EmailAddress { get; set; }

        public string Phone { get; set; }
    }

    public class CustomerName
    {
        public CustomerName()
        {
            this.Contact = new CustomerContact();
        }

        public string FirstName { get; set; }


        public string MiddleName { get; set; }


        public string LastName { get; set; }

        public CustomerContact Contact { get; set; }
    }

  modelBuilder.Entity<CustomerName>(entity =>
            {
                entity.OwnsOne(x => x.Contact).Property(c => c.EmailAddress).HasColumnName("EmailAddress").HasMaxLength(50);

                entity.OwnsOne(x => x.Contact).Property(c => c.Phone).HasColumnName("Phone").HasColumnType("Phone")
                    .HasMaxLength(25);
            });


    modelBuilder.Entity<Customer>(entity =>
            {
                entity.ToTable("Customer", "SalesLT");

                entity.Ignore(e => e.AddressCount);

                entity.HasIndex(e => e.Rowguid)
                    .HasName("AK_Customer_rowguid")
                    .IsUnique();

                entity.Property(e => e.CustomerId).HasColumnName("CustomerID");

                entity.Property(e => e.CompanyName).HasMaxLength(128);

                #region Owned Types

                entity.OwnsOne(x => x.CustomerName).Property(c => c.FirstName).HasColumnName("FirstName").IsRequired()
                    .HasColumnType("Name")
                    .HasMaxLength(50);

                entity.OwnsOne(x => x.CustomerName).Property(c => c.MiddleName).HasColumnName("MiddleName")
                    .HasColumnType("Name")
                    .HasMaxLength(50);

                entity.OwnsOne(x => x.CustomerName).Property(c => c.LastName).HasColumnName("LastName").IsRequired()
                    .HasColumnType("Name")
                    .HasMaxLength(50);

                #endregion

                entity.Property(e => e.ModifiedDate)
                    .HasColumnType("datetime")
                    .HasDefaultValueSql("(getdate())");

                entity.Property(e => e.NameStyle).HasColumnType("NameStyle");

                entity.Property(e => e.PasswordHash)
                    .IsRequired()
                    .HasMaxLength(128)
                    .IsUnicode(false);

                entity.Property(e => e.PasswordSalt)
                    .IsRequired()
                    .HasMaxLength(10)
                    .IsUnicode(false);

                entity.Property(e => e.Rowguid)
                    .HasColumnName("rowguid")
                    .HasDefaultValueSql("(newid())");

                entity.Property(e => e.SalesPerson).HasMaxLength(256);

                entity.Property(e => e.Suffix).HasMaxLength(10);

                entity.Property(e => e.Title).HasMaxLength(8);
            });

I got the error in two situations:

  1. In my base db context i was adding shadowed properties as followed:
    image
    And this code was running before my ownsmany calls. so my fault (but it was working previously)
  1. Using IEntityMap classes to configure owned types doesnt work anymore and gives the same error. Solved by configuring those types in the owner

@codehunter13 The exception was introduced to catch configuration like that. It might have worked for your model, but in general it's not supported and could've let to unexpected behavior.

Looks like i solved this too by changing configuration. Thanks.

      modelBuilder.Entity<Customer>(entity =>
            {
                entity.ToTable("Customer", "SalesLT");

                entity.Ignore(e => e.AddressCount);

                entity.HasIndex(e => e.Rowguid)
                    .HasName("AK_Customer_rowguid")
                    .IsUnique();

                entity.Property(e => e.CustomerId).HasColumnName("CustomerID");

                entity.Property(e => e.CompanyName).HasMaxLength(128);

                #region Owned Types

                var ownedCustName = entity.OwnsOne(x => x.CustomerName);

                ownedCustName.Property(c => c.FirstName).HasColumnName("FirstName").IsRequired()
                    .HasColumnType("Name")
                    .HasMaxLength(50);

                ownedCustName.Property(c => c.MiddleName).HasColumnName("MiddleName")
                    .HasColumnType("Name")
                    .HasMaxLength(50);

                ownedCustName.Property(c => c.LastName).HasColumnName("LastName").IsRequired()
                    .HasColumnType("Name")
                    .HasMaxLength(50);

                var ownedContact = ownedCustName.OwnsOne(x => x.Contact);

                ownedContact.Property(c => c.EmailAddress).HasColumnName("EmailAddress").HasMaxLength(50);

                ownedContact.Property(c => c.Phone).HasColumnName("Phone").HasColumnType("Phone")
                    .HasMaxLength(25);
                #endregion

                entity.Property(e => e.ModifiedDate)
                    .HasColumnType("datetime")
                    .HasDefaultValueSql("(getdate())");

                entity.Property(e => e.NameStyle).HasColumnType("NameStyle");

                entity.Property(e => e.PasswordHash)
                    .IsRequired()
                    .HasMaxLength(128)
                    .IsUnicode(false);

                entity.Property(e => e.PasswordSalt)
                    .IsRequired()
                    .HasMaxLength(10)
                    .IsUnicode(false);

                entity.Property(e => e.Rowguid)
                    .HasColumnName("rowguid")
                    .HasDefaultValueSql("(newid())");

                entity.Property(e => e.SalesPerson).HasMaxLength(256);

                entity.Property(e => e.Suffix).HasMaxLength(10);

                entity.Property(e => e.Title).HasMaxLength(8);
            });

@AndriySvyryd Yep, this is a breaking change. And I can change code, but it's not cool that I have to change ContextModelSnapshot, i.e. I have no chance for rollback now as I understood.

System.InvalidOperationException: The type 'Connect.Device.BusinessModel.Values.OrganizationAddress' cannot be configured as non-owned because an owned entity type with the same name already exists.
   at Microsoft.EntityFrameworkCore.Metadata.Internal.InternalModelBuilder.Entity(TypeIdentity& type, ConfigurationSource configurationSource, Nullable`1 shouldBeOwned)
   at Microsoft.EntityFrameworkCore.Metadata.Internal.InternalModelBuilder.Entity(String name, ConfigurationSource configurationSource, Nullable`1 shouldBeOwned)
   at Microsoft.EntityFrameworkCore.Metadata.Builders.OwnedNavigationBuilder.FindRelatedEntityType(String relatedTypeName, String navigationName)
   at Microsoft.EntityFrameworkCore.Metadata.Builders.OwnedNavigationBuilder.HasOne(String relatedTypeName, String navigationName)
   at Microsoft.EntityFrameworkCore.Metadata.Builders.OwnedNavigationBuilder.HasOne(String navigationName)
   at Connect.Device.DAL.Migrations.Migrations.DeviceContextModelSnapshot.<>c.<BuildModel>b__0_42(OwnedNavigationBuilder b2) in C:\Users\pavelvoronin\Source\Repos\connect.device\Connect.Device.DAL.Migrations\Migrations\DeviceContextModelSnapshot.cs:line 3093
   at Microsoft.EntityFrameworkCore.Metadata.Builders.OwnedNavigationBuilder.OwnsOne(String ownedTypeName, String navigationName, Action`1 buildAction)
   at Connect.Device.DAL.Migrations.Migrations.DeviceContextModelSnapshot.<>c.<BuildModel>b__0_39(OwnedNavigationBuilder b1) in C:\Users\pavelvoronin\Source\Repos\connect.device\Connect.Device.DAL.Migrations\Migrations\DeviceContextModelSnapshot.cs:line 3077
   at Microsoft.EntityFrameworkCore.Metadata.Builders.EntityTypeBuilder.OwnsOne(String ownedTypeName, String navigationName, Action`1 buildAction)
   at Connect.Device.DAL.Migrations.Migrations.DeviceContextModelSnapshot.<>c.<BuildModel>b__0_29(EntityTypeBuilder b) in C:\Users\pavelvoronin\Source\Repos\connect.device\Connect.Device.DAL.Migrations\Migrations\DeviceContextModelSnapshot.cs:line 3046
   at Microsoft.EntityFrameworkCore.ModelBuilder.Entity(String name, Action`1 buildAction)
   at Connect.Device.DAL.Migrations.Migrations.DeviceContextModelSnapshot.BuildModel(ModelBuilder modelBuilder) in C:\Users\pavelvoronin\Source\Repos\connect.device\Connect.Device.DAL.Migrations\Migrations\DeviceContextModelSnapshot.cs:line 3044
   at Microsoft.EntityFrameworkCore.Infrastructure.ModelSnapshot.CreateModel()
   at Microsoft.EntityFrameworkCore.Infrastructure.ModelSnapshot.get_Model()
   at Microsoft.EntityFrameworkCore.Migrations.Design.MigrationsScaffolder.ScaffoldMigration(String migrationName, String rootNamespace, String subNamespace, String language)
   at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.AddMigration(String name, String outputDir, String contextType)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(String name, String outputDir, String contextType)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigration.<>c__DisplayClass0_0.<.ctor>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0`1.<Execute>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)

The type 'Connect.Device.BusinessModel.Values.OrganizationAddress' cannot be configured as non-owned because an owned entity type with the same name already exists.
modelBuilder.Entity("Connect.Device.BusinessModel.Entities.Organization", b =>
    {
        b.OwnsOne("Connect.Device.BusinessModel.Values.OrganizationAddress", "Address", b1 =>
            {
                b1.Property<Guid>("OrganizationId");

                b1.Property<string>("City")
                    .HasMaxLength(255);

                b1.Property<int>("CountryId");

                b1.Property<string>("PostalCode")
                    .HasMaxLength(50);

                b1.Property<string>("Street")
                    .HasMaxLength(255);

                b1.HasKey("OrganizationId");

                b1.HasIndex("CountryId");

                b1.ToTable("OrganizationAddress");

                b1.HasOne("Connect.Device.BusinessModel.Entities.Country")
                    .WithMany()
                    .HasForeignKey("CountryId")
                    .OnDelete(DeleteBehavior.Restrict);

                b1.HasOne("Connect.Device.BusinessModel.Entities.Organization")
                    .WithOne("Address")
                    .HasForeignKey("Connect.Device.BusinessModel.Values.OrganizationAddress", "OrganizationId")
                    .OnDelete(DeleteBehavior.Cascade);

                b1.OwnsOne("Connect.Device.BusinessModel.Values.House", "House", b2 =>
                    {
                        b2.Property<Guid>("OrganizationAddressOrganizationId");

                        b2.Property<string>("Number")
                            .HasColumnName("HouseNumber")
                            .HasMaxLength(50);

                        b2.Property<string>("Suffix")
                            .HasColumnName("HouseNumberSuffix")
                            .HasMaxLength(50);

                        b2.HasKey("OrganizationAddressOrganizationId");

                        b2.ToTable("OrganizationAddress");

                        // line 3093
                        b2.HasOne("Connect.Device.BusinessModel.Values.OrganizationAddress")
                            .WithOne("House")
                            .HasForeignKey("Connect.Device.BusinessModel.Values.House", "OrganizationAddressOrganizationId")
                            .OnDelete(DeleteBehavior.Cascade);
                    });
            });

And org configuration now looks like this:

public void Configure(EntityTypeBuilder<Organization> builder)
{
    builder.ToTable("Organization");

    builder.Property(_ => _.Version)
        .IsConcurrencyToken()
        .HasDefaultValue(0);

    builder.OwnsOne(m => m.Address, b =>
    {
        b.WithOwner().HasForeignKey("OrganizationId");

        b.ToTable("OrganizationAddress");

        b.HasOne<Country>()
            .WithMany()
            .HasForeignKey(m => m.CountryId)
            .IsRequired()
            .OnDelete(DeleteBehavior.Restrict);

        b.OwnsOne(
            m => m.House,
            bld =>
            {
                bld.Property(m => m.Number).HasColumnName("HouseNumber");
                bld.Property(m => m.Suffix).HasColumnName("HouseNumberSuffix");
            });
    });

    builder.OwnsOne(
        m => m.ExternalIds,
        act => { act.ToTable("OrganizationExternalIds"); });

    builder.OwnsOne(
        m => m.ExternalReferences,
        act => { act.ToTable("OrganizationExternalReferences"); });

    builder.Property(m => m.SendInvoiceTo).HasDefaultValue(FulfilmentPartnerSendsInvoiceTo.OurCompany);
}

@voroninp The snapshot issue __is__ a bug: https://github.com/aspnet/EntityFrameworkCore/issues/18183

Was this page helpful?
0 / 5 - 0 ratings