Объект значения как недопустимый объект в ядре asp.net 2.1

Я использовал объект значения в проекте ядра 2.0 asp.net, который правильно работал в этом проекте.

Я обновил проект до 2.1, и он выдает ошибку

Invalid object name 'EntityAdress'.

Сущность:

public class Company : AuditableEntity<long>
{
    public int SalesRepId { get; set; }
    public string Name { get; set; }
    public int StatusId { get; set; }
    public EntityAdress Addresses { get; set; }
    public string BillingAddress { get; set; }
}

public class EntityAdress : ValueObject
{
    private EntityAdress() { }
    public string Address { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public int Zip { get; set; }

    protected override IEnumerable<object> GetAtomicValues()
    {
        yield return Address;
        yield return City;
        yield return State;
        yield return Zip;
    }
}

Реализация для ValueObject точно такая же, как в Ссылке для eshopContainer с примерами объектов-значений

Пакет, который я использую для проектов, который содержит DbContext

<Project Sdk="Microsoft.NET.Sdk">


  <PropertyGroup>
    <TargetFramework>netcoreapp2.1</TargetFramework>
    <RuntimeFrameworkVersion>2.1.6</RuntimeFrameworkVersion>
  </PropertyGroup>


  <ItemGroup>
    <PackageReference Include="IdentityServer4.AspNetIdentity" Version="1.0.1" />
    <PackageReference Include="IdentityServer4.EntityFramework" Version="2.1.1" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.1.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.1.0" />
    <PackageReference Include="Microsoft.Extensions.Logging" Version="2.1.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.1.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.1.0" />
  </ItemGroup>
</Project>

Контекст:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.RemovePluralizingTableNameConvention();
    modelBuilder.OnDeleteCascading();

    modelBuilder.ApplyConfiguration(new CompanyEntityTypeConfiguraton());

    base.OnModelCreating(modelBuilder);

}

CompanyEntityTypeConfiguraton:

public class CompanyEntityTypeConfiguraton : IEntityTypeConfiguration<Company>
{
    public void Configure(EntityTypeBuilder<Company> orderConfiguration)
    {
        orderConfiguration.OwnsOne(p => p.Addresses, cb =>
        {
            cb.Property(p => p.City).HasColumnName("City");
            cb.Property(p => p.Address).HasColumnName("Address");
            cb.Property(p => p.State).HasColumnName("State");
            cb.Property(p => p.Zip).HasColumnName("Zip");
        });

    }
}

OnDeleteCascading и RemovePluralizingTableNameConvention:

public static class ModelBuilderExtensions
{
    public static void RemovePluralizingTableNameConvention(this ModelBuilder modelBuilder)
    {
        foreach (IMutableEntityType entity in modelBuilder.Model.GetEntityTypes())
        {
            entity.Relational().TableName = entity.DisplayName();
        }
    }
    public static void OnDeleteCascading(this ModelBuilder modelBuilder)
    {
        foreach (var relationship in modelBuilder.Model.GetEntityTypes().SelectMany(e => e.GetForeignKeys()))
        {
            relationship.DeleteBehavior = DeleteBehavior.Restrict;
        }
    }

}

В чем может быть причина проблем? Это проблема с версией Entity Framework или чего-то не хватает в реализациях?

1 ответ

Решение

Всегда есть некоторые изменения в реализации между версиями EF Core. Некоторые из них могут быть исправлением ошибки, из-за которой старый код может работать по-другому.

Проблема в следующем коде:

public static void RemovePluralizingTableNameConvention(this ModelBuilder modelBuilder)
{
    foreach (IMutableEntityType entity in modelBuilder.Model.GetEntityTypes())
    {
        entity.Relational().TableName = entity.DisplayName();
    }
}

Во-первых, вы должны исключить принадлежащие типы (помните, что принадлежащие типы все еще являются сущностями в EF Core, поэтому включены в GetEntityTypes()):

modelBuilder.Model.GetEntityTypes().Where(t => !t.IsOwned())

в противном случае вы изменяете поведение EF Core по умолчанию, не создавая отдельную таблицу для принадлежащего объекта (так называемое разбиение таблицы), чтобы фактически создать отдельную таблицу, следовательно, вы получаете исключение, когда EF Core создает SQL-запрос, присоединяющийся к таблице, которая выполняет не существует.

Во-вторых, вы должны вызывать этот код после всей быстрой конфигурации, потому что в начале принадлежащие объекты (в случае, если они не помечены как [Owned] атрибут) пока не определены как таковые - это происходит только после OwnsOne звонки.

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.ApplyConfiguration(new CompanyEntityTypeConfiguraton());

    base.OnModelCreating(modelBuilder);

    modelBuilder.RemovePluralizingTableNameConvention();
    modelBuilder.OnDeleteCascading();
}
Другие вопросы по тегам