代码之家  ›  专栏  ›  技术社区  ›  Rashik

值对象在ASP.NET Core 2.1中为无效对象

  •  2
  • Rashik  · 技术社区  · 6 年前

    我在ASP.NET Core2.0项目中使用了Value对象,该项目运行正常。

    我将项目更新为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的实现与 Link for the eshopContainer examples of value objects

    我用于包含 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);
    
    }
    

    公司实体类型配置:

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

    OnDelete级联和Remove复数表格名称约定:

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

    问题的原因是什么?这是实体框架版本的问题还是实现中缺少的问题?

    1 回复  |  直到 6 年前
        1
  •  3
  •   Ivan Stoev    6 年前

    在EF核心版本之间的实现中总是有一些变化。有些可能是错误修复,这会导致旧代码运行方式不同。

    问题在于此代码:

    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核心默认行为,以实际创建单独的表,因此,当EF核心构建连接到不存在的表的SQL查询时,您将得到异常。

    第二,你应该叫那个代码 之后 所有Fluent配置,因为在开始时拥有的实体(如果没有标记 [Owned] 属性)尚未标识为这样的-它仅在 OwnsOne 电话。

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.ApplyConfiguration(new CompanyEntityTypeConfiguraton());
    
        base.OnModelCreating(modelBuilder);
    
        modelBuilder.RemovePluralizingTableNameConvention();
        modelBuilder.OnDeleteCascading();
    }