That is a simplified example, but I have a Student class with a Relation enum that describes the relationship between students. I store this data as a Dictionary<Student, Relation>:
public class Student
{
public int Id { get; set; }
public string? Name { get; set; }
public Dictionary<Student, Relation> Relations { get; set; } = new();
}
public enum Relation
{
None = 0,
Friend = 1,
Relative = 2
}
My goal is to create a database with students and students_relations tables, that would look something like this:
students:
| id | name |
|---|---|
| 1 | Tom |
| 2 | Alice |
| 3 | Bob |
students_relations:
| student_id | related_student_id | relation |
|---|---|---|
| 1 | 3 | 1 |
| 3 | 2 | 2 |
| 2 | 3 | 2 |
While Tom may think about Bob as a Friend, Bob may have a different opinion, so there's no entry like 3/1/1 in the table. But Relative relations are different, so there are two entries for Bob and Alice.
I'm studying the usage of Entity Framework Core to complete this task. I'm well aware, that dictionary can't be used as property with EF Core, so what is the best approach to complete the task?
I've created a StudentRelations class for this:
[PrimaryKey("StudentId", "RelatedStudentId")]
public class StudentRelations
{
[ForeignKey("StudentId")]
public Student Student { get; set; } = null!;
[ForeignKey("RelatedStudentId")]
public Student RelatedStudent { get; set; } = null!;
public Relation Relation { get; set; }
}
And here's my ApplicationContext class:
public class ApplicationContext : DbContext
{
public DbSet<Student> Students { get; set; } = null!;
public DbSet<StudentRelations> StudentRelations { get; set; } = null!;
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<StudentRelations>()
.HasOne(sr => sr.Student)
.WithMany(s => s.Relations);
modelBuilder.Entity<StudentRelations>()
.HasOne(sr => sr.RelatedStudent);
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlite("Data Source=students.db")
.UseSnakeCaseNamingConvention();;
}
}
This attempt also requires changing the Dictionary in Student class to List<StudentRelations> Relations.
It does what I need to, but still I'm wondering if I'm doing it the best way possible and if there's a way to map this table to Dictionary somehow. Or maybe my database scheme sucks and there's a better way to initialize database, so I won't need a Dictionary?