在 Entity Framework Core 中配置一对多和一对一关系

Gre*_*lle 7 entity-framework entity-framework-core

我对实体框架相当陌生,并且正在使用核心版本来学习它。我试图了解如何自定义模型关系。

我的基本模型是有一个公司实体和一个联系人实体。一个公司可以有多个联系人。公司可以有一个 KeyContact,它必须是关联联系人之一,但不是必需的。

因此,存在一对多关系,也存在一对一关系。我尝试按如下方式实现这一点(为了清楚起见,删除了大多数其他字段);

public class Company
{
    public int Id { get; set; }
    public int? KeyContactId { get; set; }
    public ICollection<Contact> Contacts { get; set; }
    public Contact KeyContact { get; set; }
}

public class Contact
{
    public int Id { get; set; }
    public int CompanyId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public Company Company { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

无法添加此迁移并显示消息;

无法确定“ICollection”类型的导航属性“Company.Contacts”表示的关系。手动配置关系,或从模型中忽略此属性。

我有点明白为什么它会抱怨这一点,但我不确定模型构建器是否有办法可以配置它,或者它是否是无效模式。我的模型构建器目前还只是基础;

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);

    modelBuilder.Entity<Company>().ToTable("Company");
    modelBuilder.Entity<Contact>().ToTable("Contact");
}
Run Code Online (Sandbox Code Playgroud)

我知道我可以在联系人表中设置一个标志来表示 IsKeyContact,但我喜欢在公司实体中拥有导航属性的想法。所以我想知道实体的含糖量有多高。

非常感谢任何帮助。

谢谢,

缺口

小智 3

通过向该方法添加以下行可以避免该异常OnModelCreating

modelBuilder.Entity<Company>().HasMany(p => p.Contacts).WithOne(d => d.Company).HasForeignKey(d => d.CompanyId);
Run Code Online (Sandbox Code Playgroud)

这配置了Company.Contacts-Contact.Company关系。默认情况下,该Company.KeyContact关系的配置就像以下行位于该OnModelCreating方法中一样:

modelBuilder.Entity<Company>().HasOne(e => e.KeyContact).WithMany().HasForeignKey(e => e.KeyContactId);
Run Code Online (Sandbox Code Playgroud)

因此,一个联系人可以是多个公司的 KeyContact。为了确保联系人最多可以是一个公司的 KeyContact,Company.KeyContact可以通过方法中的以下行配置关系OnModelCreating

modelBuilder.Entity<Company>().HasOne(e => e.KeyContact).WithOne().HasForeignKey<Company>(e => e.KeyContactId);
Run Code Online (Sandbox Code Playgroud)

但请注意:这并不能确保 KeyContact 是联系人的成员。