简体   繁体   English

插入/更新多个到多个实体框架。我该怎么做?

[英]Insert/Update Many to Many Entity Framework . How do I do it?

I'm using EF4 and new to it. 我正在使用EF4和它的新功能。 I have a many to many in my project and cannot seem to work out how to insert or update. 我的项目中有很多对很多,似乎无法解决如何插入或更新。 I have build a small project just to see how it should be coded. 我已经构建了一个小项目,只是为了看它应该如何编码。

Suppose I have 3 tables 假设我有3个表

  1. Class : ClassID-ClassName 类:ClassID-ClassName
  2. Student : StudentID-FirstName-Surname 学生:StudentID-FirstName-Surname
  3. StudentClass : StudentID-ClassID StudentClass:StudentID-ClassID

After adding all the relationship and updated the model via model browser I have noticed that StudentClass does not appear, this seems to be default behaviour. 添加所有关系并通过模型浏览器更新模型后,我注意到StudentClass没有出现,这似乎是默认行为。

Now I need to do both an Insert and Update. 现在我需要同时进行插入和更新。 How do you do it? 你怎么做呢? Any code samples or link where I can download an example, or can you spare 5 mins? 我可以下载示例的任何代码示例或链接,还是可以节省5分钟?

In terms of entities (or objects) you have a Class object which has a collection of Students and a Student object that has a collection of Classes . 就实体(或对象)而言,您有一个Class对象,该对象具有Students集合和一个具有Classes集合的Student对象。 Since your StudentClass table only contains the Ids and no extra information, EF does not generate an entity for the joining table. 由于您的StudentClass表仅包含ID并且没有额外信息,因此EF不会为连接表生成实体。 That is the correct behaviour and that's what you expect. 这是正确的行为,这就是你所期望的。

Now, when doing inserts or updates, try to think in terms of objects. 现在,在进行插入或更新时,请尝试根据对象进行思考。 Eg if you want to insert a class with two students, create the Class object, the Student objects, add the students to the class Students collection add the Class object to the context and call SaveChanges : 例如,如果要插入一个包含两个学生的Class ,则创建Class对象, Student对象,将学生添加到类Students集合中将Class对象添加到上下文并调用SaveChanges

using (var context = new YourContext())
{
    var mathClass = new Class { Name = "Math" };
    mathClass.Students.Add(new Student { Name = "Alice" });
    mathClass.Students.Add(new Student { Name = "Bob" });

    context.AddToClasses(mathClass);
    context.SaveChanges();
}

This will create an entry in the Class table, two entries in the Student table and two entries in the StudentClass table linking them together. 这将在Class表中创建一个条目,在Student表中创建两个条目,在StudentClass表中创建两个条目将它们链接在一起。

You basically do the same for updates. 您基本上也会对更新做同样的事情。 Just fetch the data, modify the graph by adding and removing objects from collections, call SaveChanges . 只需获取数据,通过添加和删除集合中的对象来修改图形,调用SaveChanges Check this similar question for details. 查看此类似问题了解详情。

Edit : 编辑

According to your comment, you need to insert a new Class and add two existing Students to it: 根据您的评论,您需要插入一个新Class并向其添加两个现有Students

using (var context = new YourContext())
{
    var mathClass= new Class { Name = "Math" };
    Student student1 = context.Students.FirstOrDefault(s => s.Name == "Alice");
    Student student2 = context.Students.FirstOrDefault(s => s.Name == "Bob");
    mathClass.Students.Add(student1);
    mathClass.Students.Add(student2);

    context.AddToClasses(mathClass);
    context.SaveChanges();
}

Since both students are already in the database, they won't be inserted, but since they are now in the Students collection of the Class , two entries will be inserted into the StudentClass table. 由于两个学生都已经在数据库中,因此不会插入它们,但由于它们现在位于ClassStudents集合中,因此将在StudentClass表中插入两个条目。

Try this one for Updating: 试试这个更新:

[HttpPost]
public ActionResult Edit(Models.MathClass mathClassModel)
{
    //get current entry from db (db is context)
    var item = db.Entry<Models.MathClass>(mathClassModel);

    //change item state to modified
    item.State = System.Data.Entity.EntityState.Modified;

    //load existing items for ManyToMany collection
    item.Collection(i => i.Students).Load();

    //clear Student items          
    mathClassModel.Students.Clear();

    //add Toner items
    foreach (var studentId in mathClassModel.SelectedStudents)
    {
        var student = db.Student.Find(int.Parse(studentId));
        mathClassModel.Students.Add(student);
    }                

    if (ModelState.IsValid)
    {
       db.SaveChanges();
       return RedirectToAction("Index");
    }

    return View(mathClassModel);
}

I wanted to add my experience on that. 我想在此加上我的经验。 Indeed EF, when you add an object to the context, it changes the state of all the children and related entities to Added. 实际上,当您将对象添加到上下文时,它会将所有子项和相关实体的状态更改为“已添加”。 Although there is a small exception in the rule here: if the children/related entities are being tracked by the same context, EF does understand that these entities exist and doesn't add them. 虽然规则中存在一个小例外:如果孩子/相关实体被相同的上下文跟踪,EF确实理解这些实体存在并且不添加它们。 The problem happens when for example, you load the children/related entities from some other context or a web ui etc and then yes, EF doesn't know anything about these entities and goes and adds all of them. 例如,当您从其他某个上下文或web ui等加载子/相关实体然后是,EF不知道有关这些实体的任何内容并且添加所有这些实体时,就会出现问题。 To avoid that, just get the keys of the entities and find them (eg context.Students.FirstOrDefault(s => s.Name == "Alice")) in the same context in which you want to do the addition. 为了避免这种情况,只需获取实体的密钥并在要添加的相同上下文中找到它们(例如context.Students.FirstOrDefault(s => s.Name == "Alice"))

I use the following way to handle the many-to-many relationship where only foreign keys are involved. 我使用以下方法来处理只涉及外键的多对多关系。

So for inserting : 所以插入

public void InsertStudentClass (long studentId, long classId)
{
    using (var context = new DatabaseContext())
    {
        Student student = new Student { StudentID = studentId };
        context.Students.Add(student);
        context.Students.Attach(student);

        Class class = new Class { ClassID = classId };
        context.Classes.Add(class);
        context.Classes.Attach(class);

        student.Classes = new List<Class>();
        student.Classes.Add(class);

        context.SaveChanges();
    }
}

For deleting , 删除

public void DeleteStudentClass(long studentId, long classId)
{
    Student student = context.Students.Include(x => x.Classes).Single(x => x.StudentID == studentId);

    using (var context = new DatabaseContext())
    {
        context.Students.Attach(student);
        Class classToDelete = student.Classes.Find(x => x.ClassID == classId);
        if (classToDelete != null)
        {
            student.Classes.Remove(classToDelete);
            context.SaveChanges();
        }
    }
}

In entity framework, when object is added to context, its state changes to Added. 在实体框架中,当将对象添加到上下文时,其状态将更改为“已添加”。 EF also changes state of each object to added in object tree and hence you are either getting primary key violation error or duplicate records are added in table. EF还会更改在对象树中添加的每个对象的状态,因此您要么获得主键冲突错误,要么在表中添加重复记录。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 实体框架如何在多对多关系中插入唯一值而无需手动检查 - Entity Framework how do I INSERT unique value on many to many relationship without having to do manual check 如何使用具有多对多关系的 Entity Framework Core 5 添加和更新项目? - How do I add and update items using Entity Framework Core 5 that have many to many relationships? 如何在实体框架中将一个实体映射到许多实体? - How do I map one entity to many entities in Entity Framework? 实体框架6多对多插入更新 - Entity framework 6 many to many insert update 多对多插入或更新实体框架 - Insert or Update Entity Framework Many-to-Many 实体框架:多对多关系,插入和更新 - Entity Framework : many to many relationship , Insert and update 多对多实体框架核心插入和更新 - Many to many entity framework core insert and update 在实体框架中多对多插入/更新6可联接 - Insert/Update Many to Many in an Entity Framework 6 Jointable 如何使用实体框架C#创建和插入一对多对象 - How do I create and insert one-to-many object with entity framework c# 如何在Entity Framework 5中表达“有很多通过”的关系? - How do I express a “has many through” relationship in Entity Framework 5?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM