Insérer / mettre à jour plusieurs à plusieurs Entity Framework. Comment dois-je faire?
J'utilise EF4 et nouveau. J'ai beaucoup à beaucoup dans mon projet et ne peut pas sembler travailler sur la façon d'insérer ou de mettre à jour. J'ai construit un petit projet juste pour voir comment il devrait être codé.
Supposons que j'ai 3 tables
- Classe: ClassID-ClassName
- Étudiant: StudentID-Prénom-Nom De Famille
- StudentClass: StudentID-ClassID
Après avoir ajouté toute la relation et mis à jour le modèle via le navigateur de modèle, j'ai remarqué que StudentClass ne le fait pas apparaissent, cela semble être un comportement par défaut.
Maintenant, je dois faire à la fois une insertion et une mise à jour. Comment voulez-vous faire? Des exemples de code ou un lien où je peux télécharger un exemple, ou pouvez-vous épargner 5 minutes?
5 réponses
, En termes d'entités (ou des objets), vous avez une Class
objet qui possède une collection de Students
et a Student
objet qui a une collection de Classes
. Étant donné que votre table StudentClass
ne contient que les ID et aucune information supplémentaire, EF ne génère pas d'entité pour la table de jointure. C'est le bon comportement et c'est ce que vous attendez.
Maintenant, lorsque vous faites des insertions ou des mises à jour, essayez de penser en termes d'objets. Par exemple, si vous voulez insérer une classe avec deux étudiants, créez l'objet Class
, le Student
objets, ajouter les étudiants à la classe Students
collection ajouter l'objet Class
au contexte et appeler 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();
}
Cela créera une entrée dans la table Class
, Deux entrées dans la table Student
et deux entrées dans la table StudentClass
les reliant ensemble.
Vous faites essentiellement la même chose pour les mises à jour. Récupérez simplement les données, modifiez le graphique en ajoutant et en supprimant des objets des collections, appelez SaveChanges
. Vérifiez cette question similaire pour détail.
Modifier :
Selon votre commentaire, vous devez insérer un nouveau Class
et y ajouter deux Students
existants:
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();
}
Comme les deux étudiants sont déjà dans la base de données, ils ne seront pas insérés, mais comme ils sont maintenant dans la collection Students
de la Class
, Deux entrées seront insérées dans la table StudentClass
.
Essayez celui-ci pour la mise à jour:
[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);
}
Je voulais ajouter mon expérience. En effet EF, lorsque vous ajoutez un objet au contexte, il change L'état de tous les enfants et entités associées à Ajouté. Bien qu'il y ait une petite exception dans la règle ici: si les enfants/entités liées sont suivis par le même contexte, EF comprend que ces entités existent et ne les ajoute pas. Le problème se produit lorsque, par exemple, vous chargez les enfants / entités associées à partir d'un autre contexte ou d'une interface utilisateur web, etc., puis Oui, EF ne sait rien de ces entités et va et ajoute tous. Pour éviter cela, il suffit d'obtenir les clés des entités et de les trouver (par exemple context.Students.FirstOrDefault(s => s.Name == "Alice"))
dans le même contexte dans lequel vous voulez faire l'addition.
Dans entity framework, lorsque l'objet est ajouté au contexte, son état devient ajouté. EF change également l'état de chaque objet ajouté dans l'arborescence des objets et vous obtenez donc une erreur de violation de clé primaire ou des enregistrements en double sont ajoutés dans la table.
J'utilise la manière suivante pour gérer la relation plusieurs à plusieurs où seules les clés étrangères sont impliquées.
Donc, pour insertion:
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();
}
}
Pour suppression de,
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();
}
}
}