Lucian Bumb
Lucian Bumb

Reputation: 2881

Insert records in many to many not working with Entity Framework

I want to insert 2 new records in their tables and also to create the relation many to many.

There are a lot of questions with this topic, I tried many of the answers and now I have no idea why my code is not working.

Please help me!

This is the code:

class Program
{
    static void Main(string[] args)
    {
        MyContext db = new MyContext();

        var st1 = new Student() { Name = "Joe" };
        var c1 = new Course() { Name = "Math" };

        db.Courses.Attach(c1);
        st1.Courses.Add(c1);
        db.Students.Add(st1);         

        db.SaveChanges();            
    }       
}
public class Student
{
 public Student()
    {
        Courses = new HashSet<Course>();
    }
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Course> Courses { get; set; }
}
public class Course
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Student> Students { get; set; }
}
public class MyContext : DbContext
{
    public DbSet<Student> Students { get; set; }
    public DbSet<Course> Courses { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Student>()
            .HasMany(p => p.Courses)
            .WithMany(d => d.Students)
            .Map(t =>
            {
                t.MapLeftKey("studentId");
                t.MapRightKey("courseid");
                t.ToTable("StudentCourse");
            });

        base.OnModelCreating(modelBuilder);
    }

}

Edit: Like sugested, I initialized the Courses:

 public Student()
    {
        Courses = new HashSet<Course>();
    }

and now I get this error on db.SaveChanges();

An error occurred while saving entities that do not expose foreign key properties for their relationships. The EntityEntries property will return null because a single entity cannot be identified as the source of the exception. Handling of exceptions while saving can be made easier by exposing foreign key properties in your entity types. See the InnerException for details.

Upvotes: 1

Views: 96

Answers (2)

Gert Arnold
Gert Arnold

Reputation: 109119

You're apparently trying to add a new Student to the database and associate it to an existing Course. The problem is that you attach a new Course entity to the context without a proper primary key.

It certainly is a good idea to use a so-called stub entity here, because it saves a roundtrip to the database to fetch an existing Course, but the primary key is required for EF to create a correct association record. It's even the only property you need to set in this Course stub:

var st1 = new Student() { Name = "Joe" };
var c1 = new Course() { CourseId = 123 };

db.Courses.Attach(c1);
st1.Courses.Add(c1);
db.Students.Add(st1);         

If you want to add a new course and a new student, you should Add both of them:

db.Courses.Add(c1);
st1.Courses.Add(c1);
db.Students.Add(st1);        

Upvotes: 1

Dan
Dan

Reputation: 1018

Your code isn't initialising the ICollection object in either class.

public class Student
{
    private Student()
    {
        Courses = new List<Course>();
    }

    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Course> Courses { get; set; }
}

Edit

Try changing your modelBuilder code to the following

modelBuilder.Entity<Student>()
            .HasMany<Course>(s => s.Courses)
            .WithMany(c => c.Students)
            .Map(cs =>
                    {
                        cs.MapLeftKey("StudentRefId");
                        cs.MapRightKey("CourseRefId");
                        cs.ToTable("StudentCourse");
                    });

Code sample taken directly from:

http://www.entityframeworktutorial.net/code-first/configure-many-to-many-relationship-in-code-first.aspx

Upvotes: 0

Related Questions