C
C#2y ago
Luciferno

EF Core many-to-many relation error

This is the error I am getting : And I don't really know how to fix it. These are my modals
public class Student
{
public Guid Id { get; set; }

public User User { get; set; }

[SwaggerIgnore]
public int StudentNumber { get; set; }

[JsonIgnore]
public ICollection<Class>? Classes { get; set; }
[JsonIgnore]
public List<ClassStudent> ClassStudents { get; set; }
}

public class Class
{
public Guid Id { get; set; }

public string ClassName { get; set; }

public string ClassRoom { get; set; }

[SwaggerIgnore]
public ICollection<Student>? Students { get; set; }
[JsonIgnore]
public List<ClassStudent> ClassStudents { get; set; }

public Guid TeacherForeignKey { get; set; }

[JsonIgnore]
public Teacher? Teacher { get; set; }
}

public class ClassStudent
{
public DateTime StartDate { get; set; }

public Guid ClassId { get; set; }
public Class Class { get; set; }

public Guid StudentId { get; set; }
public Student Student { get; set; }
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Class>()
.HasOne(p => p.Teacher)
.WithMany(x => x.Classes)
.HasForeignKey(x => x.TeacherForeignKey);

modelBuilder.Entity<Class>()
.HasMany(x => x.Students)
.WithMany(x => x.Classes)
.UsingEntity<ClassStudent>(
x => x.HasOne(x => x.Student).WithMany(x => x.ClassStudents).HasForeignKey(x => x.StudentId),
x => x.HasOne(x => x.Class).WithMany(x => x.ClassStudents).HasForeignKey(x => x.ClassId),
x =>
{
x.Property(pt => pt.StartDate).HasDefaultValueSql("CURRENT_TIMESTAMP");
x.HasKey(x => new { x.ClassId, x.StudentId });
}
);

modelBuilder.Entity<Student>().Property(x => x.StudentNumber).ValueGeneratedOnAdd();
}
public class Student
{
public Guid Id { get; set; }

public User User { get; set; }

[SwaggerIgnore]
public int StudentNumber { get; set; }

[JsonIgnore]
public ICollection<Class>? Classes { get; set; }
[JsonIgnore]
public List<ClassStudent> ClassStudents { get; set; }
}

public class Class
{
public Guid Id { get; set; }

public string ClassName { get; set; }

public string ClassRoom { get; set; }

[SwaggerIgnore]
public ICollection<Student>? Students { get; set; }
[JsonIgnore]
public List<ClassStudent> ClassStudents { get; set; }

public Guid TeacherForeignKey { get; set; }

[JsonIgnore]
public Teacher? Teacher { get; set; }
}

public class ClassStudent
{
public DateTime StartDate { get; set; }

public Guid ClassId { get; set; }
public Class Class { get; set; }

public Guid StudentId { get; set; }
public Student Student { get; set; }
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Class>()
.HasOne(p => p.Teacher)
.WithMany(x => x.Classes)
.HasForeignKey(x => x.TeacherForeignKey);

modelBuilder.Entity<Class>()
.HasMany(x => x.Students)
.WithMany(x => x.Classes)
.UsingEntity<ClassStudent>(
x => x.HasOne(x => x.Student).WithMany(x => x.ClassStudents).HasForeignKey(x => x.StudentId),
x => x.HasOne(x => x.Class).WithMany(x => x.ClassStudents).HasForeignKey(x => x.ClassId),
x =>
{
x.Property(pt => pt.StartDate).HasDefaultValueSql("CURRENT_TIMESTAMP");
x.HasKey(x => new { x.ClassId, x.StudentId });
}
);

modelBuilder.Entity<Student>().Property(x => x.StudentNumber).ValueGeneratedOnAdd();
}
4 Replies
Kouhai
Kouhai2y ago
StudentId in ClassStudent isn't nullable, which would introduce a cyclic cascade paths
Luciferno
Luciferno2y ago
And how can I fix that?
Kouhai
Kouhai2y ago
If StudentId is not nullable, it means it's required So let's say you deleted a ClassStudent row, that in turn would delete it's respective Student row, that row references ClassStudents so it'll try to delete them, which in turn tries to delete their respective Student and now you have cyclic cascade
Yawnder
Yawnder2y ago
The way to address that: You remove a cascading path. For example, if Delete A -> Delete B and Delete B -> Delete A, you go in either A or B and you say not to cascade the delete. (Well, not to cascade anything.)