protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Pessoa>()
.HasMany(p => p.Turmas)
.WithMany(t => t.Pessoas)
.UsingEntity<Matricula>(
r => r.HasOne<Turma>(t => t.Turma).WithMany(t => t.Matriculas).HasForeignKey(m => m.TurmaId),
l => l.HasOne<Pessoa>(p => p.Pessoa).WithMany(p => p.Matriculas).HasForeignKey(m => m.PessoaId)
);
modelBuilder.Entity<Matricula>()
.HasIndex(m => m.PessoaId)
.IsUnique()
.HasFilter("[Ativo] = 1")
;
modelBuilder.Entity<Presenca>()
.HasOne(p => p.Aula)
.WithMany(a => a.Presencas)
.HasForeignKey(p => p.AulaId)
.OnDelete(DeleteBehavior.Cascade); // Se apagar uma aula, apaga as presenças.
modelBuilder.Entity<Presenca>()
.HasOne(p => p.Matricula)
.WithMany(m => m.Presencas)
.HasForeignKey(p => p.MatriculaId)
.OnDelete(DeleteBehavior.Restrict); // Se apagar presença, não apaga matrícula.
}
I'm mapping a class system so:
- Presenca: a presence to point out whether a student was present to the class or not;
- Aula: a class at a specific moment;
- Matricula: a register or an enrollment to a specific major or subject which often happens to have classes.
Therefore, the rules written in OnModelCreating basically mean:
- Matricula is the join table between Pessoa (Person) and Turma (Team) and is the result of a many-to-many relationship;
- Matricula cannot have two entries for the same PessoaId with Ativo (Active) = true; that means, a student cannot be member of two teams at a time, but might move to another in the feature, case when the former entry would have Ativo = false. So that's why I thought it is still a many-to-many relationship;
- Presenca is the join table between Matricula and Aula. The deletion policy means if an Aula is deleted, all the Presenca are as well and if a Matricula is deleted, Presenca isn't touched.