Nicolas
Nicolas

Reputation: 4756

C# - Adding data to objects with a Many-to-Many relationship

I'm creating a webapp where you can see which Teacher has which skills. For this I'm working with a code first migration (entitity framework) which is working great so far.

Here's how my model is looking

[System.ComponentModel.DataAnnotations.Schema.Table("Skills")]
public class Skill
{
    [key]
    public int ID { get; set; }
    public string SkillName { get; set; }

    public virtual List<Teacher> Teachers { get; set; }
}

[System.ComponentModel.DataAnnotations.Schema.Table("Teachers")]
public class Teacher
{
    [key]
    public int ID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    public string Campus { get; set; }

    public virtual List<Skill> Skills { get; set; }
}

public partial class AbilityDbContext : DbContext
{
    public AbilityDbContext() : base("name= DefaultConnection")
    {
        Database.SetInitializer<AbilityDbContext>(null);
    }

    public virtual DbSet<Teacher> Teachers { get; set; }
    public virtual DbSet<Skill> Skills { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Teacher>()
        .HasMany(s => s.Skills)
        .WithMany(c => c.Teachers);
        base.OnModelCreating(modelBuilder);
    }
}

and this is the migration that has been generated (so you can have a feel for how the DB looks)

public override void Up()
{
    CreateTable(
        "dbo.Skills",
        c => new
        {
            ID = c.Int(nullable: false, identity: true),
            SkillName = c.String(),
        })
        .PrimaryKey(t => t.ID);

    CreateTable(
        "dbo.Teachers",
        c => new
        {
            ID = c.Int(nullable: false, identity: true),
            FirstName = c.String(),
            LastName = c.String(),
            Email = c.String(),
            Campus = c.String(),
        })
        .PrimaryKey(t => t.ID);

    CreateTable(
        "dbo.TeacherSkills",
        c => new
        {
            Teacher_ID = c.Int(nullable: false),
            Skill_ID = c.Int(nullable: false),
        })
        .PrimaryKey(t => new { t.Teacher_ID, t.Skill_ID })
        .ForeignKey("dbo.Teachers", t => t.Teacher_ID, cascadeDelete: true)
        .ForeignKey("dbo.Skills", t => t.Skill_ID, cascadeDelete: true)
        .Index(t => t.Teacher_ID)
        .Index(t => t.Skill_ID);
}

I also generated the controllers for both Teachers and Sills, so I can add, edit and delete teachers and skill with ease.

My question is, how can I give a teacher a certain skill? Can I also generate a controller for this or do I need to create this myself? And if so, is there any optimal way I can do this?

Looking forward to any help!

Upvotes: 0

Views: 54

Answers (1)

Alberto Monteiro
Alberto Monteiro

Reputation: 6219

Assuming that you have this Seed data

using (var context = new AbilityDbContext())
{
    if (!context.Skills.Any())
    {
        context.Skills.Add(new Skill { SkillName = "C#" });
        context.Skills.Add(new Skill { SkillName = "Java" });
        context.Skills.Add(new Skill { SkillName = "Html" });
        context.Skills.Add(new Skill { SkillName = "Ruby" });
    }

    if (!context.Teachers.Any())
        context.Teachers.Add(new Teacher
        {
            FirstName = "Alberto",
            LastName = "Monteiro",
            Campus = "PICI",
            Email = "[email protected]"
        });
    context.SaveChanges();
}

To add a skill for a teacher you must load the teacher from database, then you check if the Skills property is null, if it is create a new list of skill, then find the skill from database that you want to give and use the method add, see code below.

using (var context = new AbilityDbContext())
{
    var teacher = context.Teachers.Find(1);

    teacher.Skills = teacher.Skills ?? new List<Skill>();

    teacher.Skills.Add(context.Skills.Find(1));
    teacher.Skills.Add(context.Skills.Find(2));
    context.SaveChanges();
}

Upvotes: 1

Related Questions