【问题标题】:Many-to-many connection for three models三个模型的多对多连接
【发布时间】:2019-10-08 06:39:08
【问题描述】:

我有三个模型:学校、教师和学生

public class Pupil
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    public string FavouriteLesson { get; set; }

    public SchoolEntity School { get; set; }
    public List<Teacher> Teachers { get; set; }

    public IList<DataLink> DataLink { get; set; }
}

public class SchoolEntity
{
    [Key]
    public int Id { get; set; }
    public bool DeepEnglishLearning { get; set; }
    public int? SchoolRating { get; set; }

    public List<Teacher> Teachers { get; set; }
    public List<Pupil> Pupils { get; set; }

    public IList<DataLink> DataLink { get; set; }
}

public class Teacher
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    public string Subject { get; set; }

    public SchoolEntity School { get; set; }
    public List<Pupil> Pupils { get; set; }

    public IList<DataLink> DataLink { get; set; }
}

我有用于建立连接的 DataLinks 类:

  • 一所学校可以有很多学生和老师
  • 学生可以拥有一所学校和多位老师
  • 教师可以拥有一所学校和许多学生

DataLink.cs

public class DataLink
{
   public int TeacherId { get; set; }
   public Teacher Teacher { get; set; }

   public int PupilId { get; set; }
   public Pupil Pupil { get; set; }
}

我应该如何配置OnModelCreating 方法以使其工作?

数据库上下文

public class DatabaseContext : DbContext
{
    public DatabaseContext(DbContextOptions<DatabaseContext> options)
        : base(options)
    {}

    public DbSet<SchoolEntity> SchoolTable { get; set; }
    public DbSet<Teacher> TeacherTable { get; set; }
    public DbSet<Pupil> PupilTable { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<SchoolEntity>().ToTable("School");
        modelBuilder.Entity<Teacher>().ToTable("Teacher");
        modelBuilder.Entity<Pupil>().ToTable("Pupil");

        // Is it correct?
        modelBuilder.Entity<DataLink>()
            .HasOne(dl => dl.Teacher)
            .WithMany(dl => dl.DataLink)
            .IsRequired()
            .OnDelete(DeleteBehavior.Cascade);

        modelBuilder.Entity<DataLink>()
            .HasOne(dl => dl.Pupil)
            .WithMany(dl => dl.DataLink)
            .IsRequired()
            .OnDelete(DeleteBehavior.Restrict);
    }
}

【问题讨论】:

  • @SirRufo 抱歉,我更新了问题。学生是学生
  • 学生和老师之间的多对多关系只需要DataLink。 School-Teacher 或 School-Pupil 之间的一对多关系不需要这样的数据链接表
  • @SirRufo 我更新了问题 - 从 DataLinkDatabaseContext 中删除了学校。是它应该的样子吗?

标签: c# asp.net-mvc entity-framework asp.net-core


【解决方案1】:

除非你有额外的属性来连接学生和老师,否则你根本不需要你的 DataLink 类。 EF 可以创建一个对代码优先模型不可见的连接表来处理此问题。一旦你想要一个额外的属性,它就会消失,所以明智地选择。您可以使用以下...

    public class Pupil
    {
        [Key]
        public int Id { get; set; }
        public string Name { get; set; }
        public string FavouriteLesson { get; set; }

        public SchoolEntity School { get; set; }
        public List<Teacher> Teachers { get; set; }
    }

    public class SchoolEntity
    {
        [Key]
        public int Id { get; set; }
        public bool DeepEnglishLearning { get; set; }
        public int? SchoolRating { get; set; }

        public List<Teacher> Teachers { get; set; }
        public List<Pupil> Pupils { get; set; }
    }

    public class Teacher
    {
        [Key]
        public int Id { get; set; }
        public string Name { get; set; }
        public string Subject { get; set; }

        public SchoolEntity School { get; set; }
        public List<Pupil> Pupils { get; set; }
    }

    public class DatabaseContext : DbContext
    {
        public DatabaseContext(DbContextOptions<DatabaseContext> options)
            : base(options)
        {}

        public DbSet<SchoolEntity> SchoolTable { get; set; }
        public DbSet<Teacher> TeacherTable { get; set; }
        public DbSet<Pupil> PupilTable { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<SchoolEntity>().ToTable("School");
            modelBuilder.Entity<Teacher>().ToTable("Teacher");
            modelBuilder.Entity<Pupil>().ToTable("Pupil");

            modelBuilder.Entity<Teacher>().HasRequired(r => r.School).WithMany(m => m.Teachers).HasForiegnKey(k => k.Id);
            modelBuilder.Entity<Pupil>().HasRequired(r => r.School).WithMany(m => m.Pupils).HasForiegnKey(k => k.Id);
            //This will configure many-to-many with a join table. Use .Map to set the table name and key properties manually but EF will auto-name them if you dont
            modelBuilder.Entity<Teacher>().HasMany(x => x.Pupils).WithMany(x => x.Teachers); 
        }
    }

【讨论】:

    猜你喜欢
    • 2016-09-27
    • 2021-05-16
    • 2020-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多