EF Core 2.2,在层次结构中有多个实体时,拥有的实体会作为另一个表生成

时间:2019-02-04 02:25:19

标签: asp.net-core entity-framework-core owned-types

我有一个模型,该模型具有标记为Address的类[Owned]和人员层次结构(人员,客户或雇员,然后是更多子类型,等等)。在该层次结构的不同阶段有地址,并且所有地址最终都放在一个表中,因为EF Core限于每个层次结构中的表。我希望所有来自address的属性在该人员表中出现多次(一次在任何子类型中提及),但根本不会出现!相反,我为它们每个看到FK和一个单独的地址表。

EF Core是否不支持多个拥有相同类型的成员?如果没有,我该怎么办?我没有任何流畅的API /特定配置,可能会干扰默认设置(新的空控制台项目,只有配置行是.UseSQLServer(connectionstring)

下面的示例代码:

public class SampleContext : DbContext
{
    public virtual DbSet<Address> Addresses { get; set; }
    public virtual DbSet<Customer> Customers { get; set; }
    public virtual DbSet<Employee> Employees { get; set; }
    public virtual DbSet<Person> Persons { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        if (!optionsBuilder.IsConfigured)
        {
            optionsBuilder.UseSqlServer("my connection string here");
        }
        base.OnConfiguring(optionsBuilder);
    }
}
[Owned]
public class Address
{
    public int Id { get; set; }
    public string AddressLine1 { get; set; }
    public string AddressLine2 { get; set; }
    public string AddressLine3 { get; set; }
    public string City { get; set; }
}

public class Person
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime DateOfBirth { get; set; }
}

public class Employee : Person
{
    public Address Address { get; set; }
}

public class Customer : Person
{
    public Address DeliveryAddress { get; set; }
    public Address InvoicingAddress { get; set; }
}

预期的Person表:

DeliveryAddressAddressLine1
DeliveryAddressAddressLine2
DeliveryAddressAddressLine3
DeliveryAddressAddressCity
InvoicingAddressAddressLine1
InvoicingAddressAddressLine2
InvoicingAddressAddressLine3
InvoicingAddressAddressCity
EmployeeAddressAddressLine1
EmployeeAddressAddressLine2
EmployeeAddressAddressLine3
EmployeeAddressAddressCity

生成的Person表(+意外的Address表):

EmployeeAddressAddressId
DeliveryAddressAddressId
InvoicingAddressAddressId

编辑:更新了问题,添加了上下文定义,并注意到我将Addresses作为DbSet,所以我认为这可能是原因,删除它会给我带来以下错误:

  

不能将表“ Person”用于实体类型“ Customer.DeliveryAddress#Address”,因为它已用于实体类型“ Employee.Address#Address”,并且它们的主键之间没有关系。

1 个答案:

答案 0 :(得分:1)

根据EF Core Owned Entity Types文档:

  

不支持包含拥有的实体类型的继承层次结构

您可以通过将public Address Address { get; set; }public Address DeliveryAddress { get; set; }的{​​{1}},public Address InvoicingAddress { get; set; }Employee导航属性移动到基类Customer来解决此问题如下:

Person

然后使用流畅的API进行配置,以覆盖拥有实体列名称的public class Person { public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public DateTime DateOfBirth { get; set; } public Address Address { get; set; } public Address DeliveryAddress { get; set; } public Address InvoicingAddress { get; set; } } 规则,如下所示:

Navigation_OwnedEntityProperty

现在,如果您不想将modelBuilder.Entity<Person>().OwnsOne(p => p.Address, a => { a.Property(p => p.AddressLine1).HasColumnName("EmployeeAddressLine1"); a.Property(p => p.AddressLine2).HasColumnName("EmployeeAddressLine2"); a.Property(p => p.AddressLine2).HasColumnName("EmployeeAddressLine3"); a.Property(p => p.City).HasColumnName("EmployeeAddressCity"); }).OwnsOne(p => p.DeliveryAddress, a => { a.Property(p => p.AddressLine1).HasColumnName("DeliveryAddressLine1"); a.Property(p => p.AddressLine2).HasColumnName("DeliveryAddressLine2"); a.Property(p => p.AddressLine2).HasColumnName("DeliveryAddressLine3"); a.Property(p => p.City).HasColumnName("DeliveryAddressCity"); }).OwnsOne(p => p.InvoicingAddress, a => { a.Property(p => p.AddressLine1).HasColumnName("InvoicingAddressLine1"); a.Property(p => p.AddressLine2).HasColumnName("InvoicingAddressLine2"); a.Property(p => p.AddressLine2).HasColumnName("InvoicingAddressLine3"); a.Property(p => p.City).HasColumnName("InvoicingAddressCity"); }); public Address Address { get; set; }的{​​{1}},public Address DeliveryAddress { get; set; }public Address InvoicingAddress { get; set; }导航属性移动到基类{{ 1}},则必须按照以下每种地址类型创建单独的表:

Employee