J'utilise EF4 et nouveau pour elle. J'ai plusieurs projets dans mon projet et n'arrive pas à comprendre comment insérer ou mettre à jour. J'ai construit un petit projet juste pour voir comment il devrait être codé.
Supposons que j'ai 3 tables
Après avoir ajouté toute la relation et mis à jour le modèle via le navigateur de modèle, j'ai remarqué que StudentClass n'apparaissait pas, il semble s'agir d'un comportement par défaut.
Maintenant, je dois faire une insertion et une mise à jour. Comment faites-vous? Des exemples de code ou des liens sur lesquels je peux télécharger un exemple, ou pouvez-vous épargner 5 minutes?
En termes d'entités (ou d'objets), vous avez un objet Class
qui possède une collection de Students
et un objet Student
qui possède 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 jonction. C'est le comportement correct 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
, les objets Student
, ajoutez les étudiants à la collection de classe Students
ajoutez le Class
objectez au contexte et appelez 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.
Vous faites essentiellement la même chose pour les mises à jour. Il suffit de récupérer les données, de modifier le graphique en ajoutant et en supprimant des objets des collections, appelez SaveChanges
. Vérifiez cette question similaire pour plus de détails.
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();
}
Puisque 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 StudentClass
table.
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 à ce sujet. En effet, lorsque vous ajoutez un objet au contexte, EF modifie l’état de tous les enfants et entités associées en Ajoutée. Ici, il existe une petite exception à la règle: si les enfants/entités associées sont suivis dans 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 apparentées à partir d'un autre contexte ou d'une interface Web, etc., puis, oui, EF ne sait rien de ces entités et les ajoute toutes. Pour éviter cela, récupérez simplement les clés des entités et recherchez-les (par exemple, context.Students.FirstOrDefault(s => s.Name == "Alice"))
) _ dans le même contexte que celui dans lequel vous souhaitez effectuer l'addition.
J'utilise la manière suivante pour gérer la relation plusieurs-à-plusieurs où seules des clés étrangères sont impliquées.
Donc pour insérer:
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 supprimer,
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();
}
}
}
Dans le cadre de l'entité, lorsque l'objet est ajouté au contexte, son état passe à Ajouté. EF modifie également l'état de chaque objet pour l'ajouter dans l'arborescence des objets. Par conséquent, vous obtenez une erreur de violation de clé primaire ou des enregistrements en double sont ajoutés dans la table.