Search code examples
entity-framework-coredomain-driven-designef-core-2.2ef-core-3.1

Owned Entities when updating efCore from 2.2 to 3.1


I'm migrating an existing project based on DDD design principles from efcore 2.2 to efcore 3.1. Database setup is based on the series of articles that Julie Lerman wrote a few years ago.

Generally this has been fine but I'm struggle to resolve an issued with owned entities and in particular this error message:

InvalidOperationException: The type 'ApplicationCore.Entities.UserAggregate.Email' cannot be configured as non-owned because an owned entity type with the same name already exists

The two entities are:

public class User
{
    public int Id { get; private set; }
    public Guid GuidId { get; private set; }
    public Email Email {get; private set;}
}

and it's "owned" entity

public class Email
{
    public string Address { get; private set; }
}

Formerly in EfCore 2.2 the configuration was:

private static void ConfigureUser(EntityTypeBuilder<User> builder)
{
    builder.HasKey(s => s.Id);

    builder.Property(s => s.GuidId)
            .IsRequired();

    builder.OwnsOne(u => u.Email);
}

As far as I understand what I should be doing in efcore3.1 is to update this to be:

private static void ConfigureUser(EntityTypeBuilder<User> builder)
{
    builder.HasKey(s => s.Id);

    builder.Property(s => s.GuidId)
            .IsRequired();

    builder.OwnsOne(u => u.Email).WithOwner();
}

As well as this configure method there are several more for the other entities within the OnModelCreating() method

protected override void OnModelCreating(ModelBuilder builder)
{
    builder.Entity<ForecastSetup>(ConfigureForecastSetup);
    …
    builder.Entity<User>(ConfigureUser);

    // Remove internal property
    foreach (var entityType in builder.Model.GetEntityTypes())
    {
        builder.Entity(entityType.Name).Ignore("IsDirty");
    }
}

The exception will be thrown from the builder.Entity(entityType.Name).Ignore("IsDirty") line.

And that's it. However, this makes zero difference and the same error reappears.

I can't run add-migrations to test if there is something else being setup as the exception is being thrown and I'm unsure as to what will happen if I delete the ContextModelSnapshot…


Solution

  • Thanks @IvanStoev, see the question he links to in the comments.

    The config was correct, my problem was occur when trying to remove the Shadow property

    // Remove shadow property for entities which are not owned
    foreach (var entityType in builder.Model.GetEntityTypes().Where(e => !e.IsOwned()))
    {
        builder.Entity(entityType.Name).Ignore("IsDirty");
    }