我有一个模型,该模型具有标记为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”,并且它们的主键之间没有关系。
答案 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