簡體   English   中英

插入/更新多個到多個實體框架。我該怎么做?

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

我正在使用EF4和它的新功能。 我的項目中有很多對很多,似乎無法解決如何插入或更新。 我已經構建了一個小項目,只是為了看它應該如何編碼。

假設我有3個表

  1. 類:ClassID-ClassName
  2. 學生:StudentID-FirstName-Surname
  3. StudentClass:StudentID-ClassID

添加所有關系並通過模型瀏覽器更新模型后,我注意到StudentClass沒有出現,這似乎是默認行為。

現在我需要同時進行插入和更新。 你怎么做呢? 我可以下載示例的任何代碼示例或鏈接,還是可以節省5分鍾?

就實體(或對象)而言,您有一個Class對象,該對象具有Students集合和一個具有Classes集合的Student對象。 由於您的StudentClass表僅包含ID並且沒有額外信息,因此EF不會為連接表生成實體。 這是正確的行為,這就是你所期望的。

現在,在進行插入或更新時,請嘗試根據對象進行思考。 例如,如果要插入一個包含兩個學生的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();
}

這將在Class表中創建一個條目,在Student表中創建兩個條目,在StudentClass表中創建兩個條目將它們鏈接在一起。

您基本上也會對更新做同樣的事情。 只需獲取數據,通過添加和刪除集合中的對象來修改圖形,調用SaveChanges 查看此類似問題了解詳情。

編輯

根據您的評論,您需要插入一個新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();
}

由於兩個學生都已經在數據庫中,因此不會插入它們,但由於它們現在位於ClassStudents集合中,因此將在StudentClass表中插入兩個條目。

試試這個更新:

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

我想在此加上我的經驗。 實際上,當您將對象添加到上下文時,它會將所有子項和相關實體的狀態更改為“已添加”。 雖然規則中存在一個小例外:如果孩子/相關實體被相同的上下文跟蹤,EF確實理解這些實體存在並且不添加它們。 例如,當您從其他某個上下文或web ui等加載子/相關實體然后是,EF不知道有關這些實體的任何內容並且添加所有這些實體時,就會出現問題。 為了避免這種情況,只需獲取實體的密鑰並在要添加的相同上下文中找到它們(例如context.Students.FirstOrDefault(s => s.Name == "Alice"))

我使用以下方法來處理只涉及外鍵的多對多關系。

所以插入

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

刪除

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

在實體框架中,當將對象添加到上下文時,其狀態將更改為“已添加”。 EF還會更改在對象樹中添加的每個對象的狀態,因此您要么獲得主鍵沖突錯誤,要么在表中添加重復記錄。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM