【问题标题】:Entity Framework: insert into a many-to-many relationship实体框架:插入多对多关系
【发布时间】:2017-08-23 13:05:19
【问题描述】:

为什么A和B是多对多的关系,在A表中插入记录时,B表中也会添加一条新记录?

有两个模型类,CustomerCourse。一位客户可以选择许多课程。此外,许多客户可以选择一门课程。

我遇到的问题是,当我用他选择的一些课程(例如course1course2)创建客户时,course1course2 已经在Courses 表中,但它会再次自动插入course1course2,这不是我想要的。

客户类:

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; }
}

课程类:

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

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

CustomerController, Save 方法:

[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");
}

Courses 表中有四门课程:

enter image description here

当我创建一个选择了一些课程的客户时,Customer 保存成功,CustomersCourses 也添加了数据。

但在Courses表中,客户注册的选择课程也被添加到课程表中。

enter image description here

红色三角形中的数据不是我们想要的。

任何帮助或建议将不胜感激,谢谢!

【问题讨论】:

  • 我想这完全取决于您在customer.CoursesEnrolled 中拥有的内容以及您如何填写这些内容。如果那里没有现有的课程 ID,它们当然是新课程。但你没有向我们展示这些信息,所以我们不得不猜测......
  • 感谢您的回复。原因就像ashin说的,他给出了两个解决方案。

标签: c# sql entity-framework many-to-many


【解决方案1】:

我认为每次创建新的 Customer 实例时,您都会使用 Courses 的新实例(与数据库中持久记录的 ID 相同)。 EF 将它们作为新添加的对象进行跟踪,并将它们作为保存更改的新记录插入到数据库中。有两种选择:

  1. 从上下文加载课程并将它们添加到客户实例的 CoursesEnrolled 集合中,这让 EF 知道该实体已保存在数据库中。

  2. 明确将 CoursesEnrolled 标记为 Unchanged/Detached,以便 EF 跳过它。

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

【讨论】:

  • 我尝试了您提供的这两种解决方案,它们都可以正常工作。谢谢你。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-28
  • 2011-12-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多