首页 > 解决方案 > 如何建立单向关系?

问题描述

嗨,我目前正在学习实体框架,我对关系有点困惑。给定两个模型:

public class Professor
{
    ...
    public List<Faculty> Faculties { get; set; }
}

public class Faculty 
{
    [Key] 
    public int Id { get; set; }
    [Required,MaxLength(100)]
    public string Name { get; set; }
}

我想要表学院,它应该只包含我列出的那些属性。像这样

╔════╦══════════╗
║ Id ║ Name     ║
╠════╬══════════╣
║ 1  ║ Faculty1 ║
╠════╬══════════╣
║ 2  ║ Faculty2 ║
╠════╬══════════╣
║ 3  ║ Faculty3 ║
╠════╬══════════╣
║ 4  ║ Faculty4 ║
╚════╩══════════╝

但是我在迁移后得到的是这个。

╔════╦══════════╦═════════════╗
║ Id ║ Name     ║ ProfessorId ║
╠════╬══════════╬═════════════╣
║ 1  ║ Faculty1 ║             ║
╠════╬══════════╬═════════════╣
║ 2  ║ Faculty2 ║             ║
╠════╬══════════╬═════════════╣
║ 3  ║ Faculty3 ║             ║
╠════╬══════════╬═════════════╣
║ 4  ║ Faculty4 ║             ║
╚════╩══════════╩═════════════╝

实体框架正在向表中添加一个 shadowforeignkey。如果我像这样离开它,我最终会得到这样的重复的教师条目

╔════╦══════════╦═════════════╗
║ Id ║ Name     ║ ProfessorId ║
╠════╬══════════╬═════════════╣
║ 1  ║ Faculty1 ║ 1           ║
╠════╬══════════╬═════════════╣
║ 2  ║ Faculty1 ║ 2           ║
╠════╬══════════╬═════════════╣
║ 3  ║ Faculty1 ║ 33          ║
╠════╬══════════╬═════════════╣
║ 4  ║ Faculty2 ║ 7           ║
╠════╬══════════╬═════════════╣
║ 5  ║ Faculty3 ║ 5           ║
╠════╬══════════╬═════════════╣
║ 6  ║ Faculty4 ║ 99          ║
╚════╩══════════╩═════════════╝

我希望它看起来如何?教授条目应该能够引用 1 个或多个学院条目。但教师条目不应该知道教授条目。我不想仅仅因为教授可以引用相同的教师而重复 Facutly 条目。

我究竟做错了什么?也许我的问题有点愚蠢,但我真的很困惑......

标签: entity-framework

解决方案


这条线public List<Faculty> Faculties { get; set; }让 EntityFramework 认为你有一个一对多的关系,这在英语中基本上意味着:

一位教授可以在多个学院,但一个学院可以有一位教授。

现在你可以考虑不止一种方式,

如果您认为教授只能在一个学院工作,那么您的课程应该如下:

public class Professor
{
    ...
    public int FacultyId { get; set; }
    public Faculty Faculty { get; set; }
}

public class Faculty 
{
    [Key] 
    public int Id { get; set; }
    [Required,MaxLength(100)]
    public string Name { get; set; }

    public List<Professor> Professors { get; set; }
}

在你的DbContext

modelBuilder.Entity<Faculty>().HasMany(i => i.Professors)
                              .WithOne(i => i.Faculty)
                              .HasForeignKey(i => i.FacultyId);

现在您将拥有Faculties仅包含表IDName字段的表,这些字段FacultyId将添加到Professors表中。

但另一方面,如果你认为一个教授可以在多个学院工作,一个学院可以有多个教授,这就是我们所说的Many-To-Many关系,你的结构应该如下:

public class Professor
{
    public int Id { get; set; }
    ...
    public List<ProfessorFaculty> ProfessorFaculties { get; set; }
}

public class Faculty 
{
    [Key] 
    public int Id { get; set; }
    [Required,MaxLength(100)]
    public string Name { get; set; }

    public List<ProfessorFaculty> ProfessorFaculties { get; set; }
}

public class ProfessorFaculty
{
     public int ProfessorId { get; set; }
     public Professor Professor { get; set; }
     
     public int FacultyId { get; set; }
     public Faculty Faculty { get; set; }
}

在你的DbContext

modelBuilder.Entity<ProfessorFaculty>().HasKey(i => new { i.ProfessorId, i.FacultyId });

现在,如您所见,我们添加了一个表示多对多关系的新表,并且在我们的 dbcontext 中,我们设置了新表的主键。

例如教授教授表:

  • 教授1教员1
  • 教授 1 教员 2
  • 教授1教员3
  • 教授2教员1
  • 教授2教员3

要添加教授教授:

public void AddProfessorToFaculty(int professorId, int facultyId)
{
   var professorFaculty = new ProfessorFaculty
   {
       ProfessorId = professorId,
       FacultyId  = facultyId 
   };
    
   _context.ProfessorFaculties.Add(professorFaculty);
   _context.SaveChanges();
}

推荐阅读