Собственные сущности при обновлении efCore с 2.2 до 3.1

Я переношу существующий проект, основанный на принципах проектирования DDD, с efcore 2.2 на efcore 3.1. Настройка базы данных основана на серии статей, написанных Джули Лерман несколько лет назад.

Как правило, это было нормально, но я изо всех сил пытаюсь решить проблему с принадлежащими объектами и, в частности, с этим сообщением об ошибке:

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

Эти две сущности:

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

и это "собственное" лицо

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

Ранее в EfCore 2.2 конфигурация была следующей:

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

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

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

Насколько я понимаю, что я должен делать в efcore3.1, так это обновить это так:

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

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

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

Помимо этого метода configure есть еще несколько для других сущностей в методе OnModelCreating().

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");
    }
}

Исключение будет выброшено из строки builder.Entity(entityType.Name).Ignore("IsDirty").

И это все. Однако это не имеет никакого значения, и снова появляется та же ошибка.

Я не могу запустить add-migrations, чтобы проверить, настраивается ли что-то еще, поскольку создается исключение, и я не уверен, что произойдет, если я удалю ContextModelSnapshot…


person Ross Halliday    schedule 24.03.2020    source источник
comment
Где-то в коде, не показанном здесь, у вас есть вызов modelBuilder.Entity() с типом Email в качестве аргумента/аргумента общего типа. Вы можете попробовать запустить простой запрос, такой как context.Users.ToLIst(), в отладчике VS с прерыванием при возникновении исключения и увидеть точную строку, генерирующую исключение.   -  person Ivan Stoev    schedule 24.03.2020
comment
Итак, в моем методе OnModelCreating() есть все методы Configure, затем он перебирает все объекты в build.Model, чтобы удалить свойство, которое не требуется. Я обновлю вопрос, чтобы сделать эту часть более явной.   -  person Ross Halliday    schedule 24.03.2020
comment
Скорее всего, вам нужно исключить типы сущностей с помощью IsOwned() - см. заголовок ="shadowproperties, достигаемые foreach перед созданием"> stackoverflow.com/questions/52888876/   -  person Ivan Stoev    schedule 24.03.2020
comment
Гений! это он :-) Я добавлю это в качестве ответа, ура. Вчера я отфильтровал имя самого типа, чтобы исключить их; но могли быть и другие проблемы с конфигурацией.   -  person Ross Halliday    schedule 24.03.2020


Ответы (1)


Спасибо @IvanStoev, см. вопрос, на который он ссылается, в комментариях.

Конфигурация была правильной, моя проблема возникла при попытке удалить свойство Shadow

// 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");
}
person Ross Halliday    schedule 24.03.2020