简体   繁体   中英

Entity Framework: insert into a many-to-many relationship

Why A and B in a many-to-many relationship, when inserting record to A table, a new record will be added in B table as well?

There are two model classes, Customer and Course . One customer can choose many courses. Also, one course can be chosen by many customers.

The problem I met is that when I create a customer with some courses he selected (for example course1 and course2 ), course1 and course2 are already in the Courses table, but it will automatically insert course1 and course2 again which is not what I want.

Customer class:

public class Customer
{
    public int Id { get; set; }

    [MaxLength(20)]
    public string City { get; set; }

    [Range(16,58)]
    public int  Age { get; set; }
    public Gender Gender { get; set; }

    [MaxLength(20)]
    public string Name { get; set; }

    public IList<Course> CoursesEnrolled { get; set; }
}

Course class:

public class Course
{
    public int  Id { get; set; }

    [MaxLength(50)] 
    [Required]
    public string Name { get; set; }
}

CustomerController , Save method:

[HttpPost]
public ActionResult Save( Customer customer 
{
        if (customer.Id == 0)
        {
            Customer customerInDb = new Customer()
            {
                Name = customer.Name , 
                City = customer.City ,
                Age = customer.Age ,
                Gender = customer.Gender ,
                CoursesEnrolled =  customer.CoursesEnrolled 
            };

            _context.Customers.Add(customerInDb);
        }
        else
        {
            var customerInDb = _context.Customers.SingleOrDefault(c => c.Id == customer.Id);

            if (customerInDb == null)
            {
                return HttpNotFound();
            }

            customerInDb.Name = customer.Name;
            customerInDb.Age = customer.Age;
            customerInDb.City = customer.City;
            customerInDb.Gender = customer.Gender;
            customerInDb.CoursesEnrolled = customer.CoursesEnrolled;
        }

        try
        {
            _context.SaveChanges();
        }
        catch (System.Data.Entity.Validation.DbEntityValidationException dbEx)
        {
            Exception raise = dbEx;

            foreach (var validationErrors in dbEx.EntityValidationErrors)
            {
                foreach (var validationError in validationErrors.ValidationErrors)
                {
                    string message = string.Format("{0}:{1}",
                        validationErrors.Entry.Entity.ToString(),
                        validationError.ErrorMessage);
                    raise = new InvalidOperationException(message, raise);
                }
            }

            throw raise;
        }

        return RedirectToAction("Index" , "Customer");
}

Four courses exist in the Courses table:

enter image description here

When I create a customer with some courses selected, Customer saves successfully, and CustomersCourses also added the data.

But in the Courses table, the selecting courses that the customer enrolled also are added to the courses table.

enter image description here

The data in the red triangle is not we want.

Any help or suggestions would be appreciated, thanks!

I think you use new instances of Courses (with the same ID as that of the persisted record in the database) every time a new Customer instance is created. EF tracks them as a newly added objects and inserts them to db as new records on save changes. There are a couple of options:

  1. Load Courses from the context and add them to the CoursesEnrolled collection of the customer instance, which lets EF know that the entity is already persisted in the database.

  2. Explcitly mark the CoursesEnrolled as Unchanged/Detached so that EF would skip it.

     foreach (var course in customerInDb.CoursesEnrolled) { _context.Entry(course).State = System.Data.Entity.EntityState.Unchanged; } 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM