[英]EF Core: One-to-one and One-to-many Relationships Between a Single Pair of Entities
下面是我希望使用 EF Core model 访问的一些实体的简化表示。 Company
可以与其Manager
建立可选的一对一关系,也可以与其Employee
建立一对多关系。
public class Company
{
public int Id { get; set; }
public virtual ICollection<Employee> Employees { get; set; }
public virtual Manager Manager { get; set; }
public int? ManagerId { get; set; }
}
public class Employee
{
public int Id { get; set; }
public virtual Company Company { get; set; }
public int CompanyId { get; set; }
}
public class Manager : Employee
{
}
实体以通常的方式暴露给 EF Core:
public DbSet<Company> Companies { get; set; }
public DbSet<Employee> Employees { get; set; }
我曾尝试过model他们的关系,如下:
modelBuilder.Entity<Company>()
.HasMany(item => item.Employees)
.WithOne(item => item.Company)
.HasForeignKey(item => item.CompanyId)
.IsRequired(true);
modelBuilder.Entity<Manager>()
.HasOne(item => item.Company)
.WithOne(item => item.Manager)
.HasForeignKey<Company>(item => item.ManagerId)
.IsRequired(false);
但是,在运行时,EF Core 拒绝此配置并显示消息“无法在 'Company.Manager' 和 'Employee.Company' 之间创建关系,因为 'Company.Employees' 和 'Employee.Company' 之间已经存在关系。导航可以只参与单个关系。如果要覆盖现有关系,请首先在“OnModelCreating”中的导航“Employee.Company”上调用“Ignore”。 ”
谁能建议如何配置它? 非常感谢。
当用另一个实体扩展现有的具体实体时,扩展的 class 字段将添加到同一个表中,因此您可以在一行中确定哪个员工也是经理。 这称为按层次结构表 (TPH)。
您想要的是每个类型的表 (TPT) 模式 - 尚未由开箱即用的实体提供。 更多关于那些在这里!
要在此之前自行设置,请“完全由流利的 api”定义模型,这样您就可以创建自己的关系,而无需使用实体约定。
像这样的东西(即使没有构建,它是一个记事本涂鸦)
public class Employee {
public string EmployeeId {get;set;}
public string DisplayName {get;set;}
public string WorksAtCompanyId {get;set;}
public Company WorksAtCompany {get;set; }
public string ManagesCompanyId {get;set;}
public Company ManagesCompany {get;set; }
}
modelBuilder.Entity<Employee>()
b.Property<string>("EmployeeId").HasMaxLength(36).HasColumnType("nvarchar(36)");
b.Property<string>("DisplayName").HasColumnType("nvarchar(max)");
b.Property<string>("WorksAtCompanyId").HasColumnType("nvarchar(max)");
b.Property<string>("ManagesCompanyId").HasColumnType("nvarchar(max)");
b.HasOne(d => d.WorksAtCompany).WithMany(d => d.Employees).HasPrincipalKey<Employee>(d => d.WorksAtCompanyId).HasForeignKey<Company>(d => d.CompanyId).IsRequired().OnDelete(DeleteBehavior.Restrict);
b.HasOne<Company>(d => d.ManagesCompany).WithOne<Employee>(d => d.Manager).HasPrincipalKey<Employee>(d => d.ManagesCompanyId).HasForeignKey<Company>(d => d.CompanyId).OnDelete(DeleteBehavior.Restrict);
public class Company {
public string CompanyId {get;set;}
public List<Employee> Employees {get;set;}
public string ManagerId {get;set;}
public Employee Manager {get;set;}
}
modelBuilder.Entity<Company>()
b.Property<string>("CompanyId").HasMaxLength(36).HasColumnType("nvarchar(36)");
b.Property<string>("DisplayName").HasColumnType("nvarchar(max)");
b.HasMany(d => d.Employees).WithOne<Employee>(d => d.WorksAtCompany).HasPrincipalKey<Employee>(d => d.WorksAtCompanyId).HasForeignKey<Company>(d => d.CompanyId).OnDelete(DeleteBehavior.Restrict);
b.HasOne(d => d.Manager).WithOne(d => d.ManagesCompany).HasPrincipalKey<Employee>(d => d.ManagesCompanyId).HasForeignKey<Company>(d => d.CompanyId).OnDelete(DeleteBehavior.Restrict);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.