代码之家  ›  专栏  ›  技术社区  ›  Ronan Thibaudau

EF Core 2.2,当层次结构中有多个实体时,所属实体作为另一个表生成

  •  2
  • Ronan Thibaudau  · 技术社区  · 6 年前

    我有一个班的模特 Address 标记 [Owned]

    EF Core是否不支持同一类型的多个自有成员?如果没有,我该怎么办?我没有任何可能干扰默认设置的fluent 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
    

    生成 表(+意外事件) 住址 表):

    EmployeeAddressAddressId
    DeliveryAddressAddressId
    InvoicingAddressAddressId
    

    编辑:更新了问题,添加了上下文定义,并注意到我 Addresses 作为一个DbSet,我假设这可能是原因,删除它会导致以下错误:

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

    1 回复  |  直到 6 年前
        1
  •  5
  •   TanvirArjel    6 年前

    Owned Entity Types 文档:

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

    你可以通过移动来克服这个问题 public Address Address { get; set; } , public Address DeliveryAddress { get; set; } public Address InvoicingAddress { get; set; } 来自的导航属性 Employee Customer 基类 Person

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

    然后使用fluent API进行配置,以覆盖 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");
       });
    

    现在,如果你不想搬家,你可以走了 公共广播地址{get;set;} , 公共地址InvoicingAddress{get;set;} 来自的导航属性 受雇者 基类

    modelBuilder.Entity<Employee>().OwnsOne(p => p.Address,
        a =>
        {
            a.ToTable("EmployeeAddresses");
        });
    
    modelBuilder.Entity<Customer>().OwnsOne(p => p.DeliveryAddress,
        a =>
        {
            a.ToTable("DeliveryAddresses");
        }).OwnsOne(p => p.InvoicingAddress,
        a =>
        {
            a.ToTable("InvoicingAddresses");
        });
    
    推荐文章