Impossible de mettre à jour la clé étrangère dans Entity Framework 6

J’essaie de faire une simple mise à jour de la clé étrangère, mais le script n’est jamais envoyé.

Voici le code que j’utilise:

using (var db = new MyContext()) { db.Entry(newContact).State = EntityState.Modified; newContact.ContactOwner = db.Person.Find(3); db.SaveChanges(); } 

EF6 met à jour le rest de la colonne dans la table Personnes, mais ne met pas à jour la table Contact_Id dans Personnes.

Personne entité:

 public class Person { public int Id { get; set; } public ssortingng Name { get; set; } public List ContactList { get; set; } } 

Entité de contact:

 public class Contact { public int Id { get; set; } public ssortingng Email { get; set; } public ssortingng TelNo { get; set; } public Person ContactOwner { get; set; } } 

Qu’est-ce que j’oublie ici?

S’il vous plaît aider!

Depuis que vous travaillez avec une association indépendante. Tu peux soit

  • Ajout et suppression de la relation de ContactList , mais vous devez extraire des deux Person .

     db.Entry(newContact).State = EntityState.Modified; var p1 = db.Set().Include(p => p.ContactList) .FirstOrDefault(p =>p.Id == 1); p1.ContactList.Remove(newContact); var p3 = db.Set().Include(p => p.ContactList) .FirstOrDefault(p => p.Id == 3); p3.ContactList.Add(newContact); db.SaveChanges(); 
  • Ou vous pouvez utiliser un object déconnecté, mais vous devez gérer manuellement la relation.

     db.Entry(newContact).State = EntityState.Modified; var p1 = new Person { Id = 1 }; db.Entry(p1).State = EntityState.Unchanged; var p3 = new Person { Id = 3 }; db.Entry(p3).State = EntityState.Unchanged; var manager = ((IObjectContextAdapter)db).ObjectContext.ObjectStateManager; manager.ChangeRelationshipState(newContact, p1, item => item.ContactOwner, EntityState.Deleted); manager.ChangeRelationshipState(newContact, p3, item => item.ContactOwner, EntityState.Added); db.SaveChanges(); 

PS

Vous devrez peut-être reconsidérer l’ajout de la valeur de la clé étrangère pour tout simplifier, en mettant à jour la clé étrangère simplement en mentionnant l’identifiant.

Voir ce post pour plus d’informations.

C’est ce que j’ai construit jusqu’à la fin de la matinée, je devrais être refactorisé un peu plus …

  protected static async Task SaveEntity(t obj) where t : BaseModel { try { using (DatabaseContext db = GetDbContext()) { //get the basemodel/fk reference properties IEnumerable props = obj.GetType().GetProperties().Where(p => p.PropertyType.BaseType == typeof(BaseModel)); if (obj.Id <= 0) {//insert db.Entry(obj).State = EntityState.Added; //set fk reference props to unchanged state foreach (PropertyInfo prop in props) { Object val = prop.GetValue(obj); if (val != null) { db.Entry(val).State = EntityState.Unchanged; } } //do insert return await db.SaveChangesAsync(); } else {//update //get the posted fk values, and set them to null on the obj (to avaid dbContext conflicts) Dictionary updateFKValues = new Dictionary(); foreach (PropertyInfo prop in props) { BaseModel val = (BaseModel)prop.GetValue(obj); if (val == null) { updateFKValues.Add(prop.Name, null); } else { updateFKValues.Add(prop.Name, val.Id); } prop.SetValue(obj, null); } //dbContext creation may need to move to here as per below working example t dbObj = (t)db.Set(typeof(t)).Find(new object[] { obj.Id }); //this also differs from example //update the simple values db.Entry(dbObj).CurrentValues.SetValues(obj); //update complex values foreach (PropertyInfo prop in props) { Object propValue = null; if (updateFKValues[prop.Name].HasValue) { propValue = (BaseModel)db.Set(prop.PropertyType).Find(new object[] { updateFKValues[prop.Name] }); } prop.SetValue(dbObj, propValue); if (propValue != null) { db.Entry(propValue).State = EntityState.Unchanged; } } //do update return await db.SaveChangesAsync(); } } } catch (Exception ex) { ExceptionHelper.Log(ex); throw; } } 

En gros, cela se produit car EntryState.Modified ne fait que rechercher des propriétés scalaires (types primitifs ) et qu’avec une association indépendante (votre cas), vous ne l’avez pas.

Il existe plusieurs moyens pour y parvenir, @Yuliam en a souligné quelques-uns et vous pouvez en trouver davantage.