Je suis nouveau dans Entity Framework et ce comportement me perturbe:
[Table("ClinicProfile")]
public class ClinicProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[ForeignKey("ContactData")]
public int ContactDataId { get; set; }
public ContactData ContactData { get; set; }
}
[Table("ContactData")]
public class ContactData
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
...
}
Lors de l'insertion de la nouvelle entité, tout fonctionne correctement - ContactData est enregistré dans la table et la clé étrangère est attribuée:
clinicProfile.ContactData = contactData;
SharedContext.Current.Entry(clinicProfile).State = EntityState.Added;
SharedContext.Current.SaveChanges();
Mais lorsque j'essaie de mettre à jour cette entité, ContactData ne reçoit pas de mise à jour.
clinicProfile.ContactData = contactData;
SharedContext.Current.Entry(clinicProfile).State = EntityState.Modified;
SharedContext.Current.SaveChanges();
Dois-je marquer ContactData comme modifié aussi? Ou est-ce que je fais juste quelque chose de mal?
EDIT-2 - La réponse
Utilisez ce code, si contactData est le nouvel objet de la base de données, avec le nouvel identifiant d'objet.
clinicProfile.ContactData = contactData;
SharedContext.Current.Entry(clinicProfile).State = EntityState.Modified;
SharedContext.Current.SaveChanges();
Si vous voulez juste mettre à jour l'ancien contactData, il serait correct d'utiliser ce code:
SharedContext.Current.Entry(contactData).State = EntityState.Modified;
SharedContext.Current.SaveChanges();
EDIT - capture instantanée de code étendue
Code du contrôleur MVC, publication à partir de la page. Les paramètres "clinicProfile" et "contactData", "adresseDonnées" contiennent des identifiants valides.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Modify(ClinicProfile clinicProfile, ContactData contactData, AdressData adressData)
{
ViewBag.Id = clinicProfile.Id;
if (ModelState.IsValid)
{
if (clinicProfile.Id != 0)
{
clinicProfile.ContactData = contactData;
clinicProfile.AdressData = adressData;
clinicProfile.AdressDataComposed = adressData.ComposeData();
clinicProfile.ContactDataComposed = contactData.ComposeData();
SharedContext.Current.Entry(clinicProfile).State = EntityState.Modified;
SharedContext.Current.SaveChanges();
Config.SaveClinicPhoto(clinicProfile.ClinicImageUpload, clinicProfile.Id);
Config.SaveClinicPreviewPhoto(clinicProfile.ClinicImageUpload, clinicProfile.Id);
return View(new ClinicProfileComposite { AdressData = adressData, ClinicProfile = clinicProfile, ContactData = contactData });
}
{
clinicProfile.ContactData = contactData;
clinicProfile.AdressData = adressData;
clinicProfile.AdressDataComposed = adressData.ComposeData();
clinicProfile.ContactDataComposed = contactData.ComposeData();
SharedContext.Current.Entry(clinicProfile).State = EntityState.Added;
SharedContext.Current.SaveChanges();
Config.SaveClinicPhoto(clinicProfile.ClinicImageUpload, clinicProfile.Id);
Config.SaveClinicPreviewPhoto(clinicProfile.ClinicImageUpload, clinicProfile.Id);
return RedirectToAction("Info", new { id = clinicProfile.Id });
}
}
ViewBag.Id = clinicProfile.Id;
return View(new ClinicProfileComposite { AdressData = adressData, ClinicProfile = clinicProfile, ContactData = contactData });
}
vous venez de perdre la propriété de clé étrangère
[Table("ClinicProfile")]
public class ClinicProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
//[ForeignKey("ContactData")] here the wrong place
public int ContactDataId { get; set; }
[ForeignKey("ContactDataId")] // here the correct place
public ContactData ContactData { get; set; }
}
[Table("ContactData")]
public class ContactData
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
...
}
et lorsque vous souhaitez définir les données de clé étrangère, vous pouvez définir la valeur ContactDataId ou extraire ContactData de la base de données en tant qu'objet et le définir dans ClinicProfile.
// according to your data posted later
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Modify(ClinicProfile clinicProfile, ContactData contactData, AdressData adressData)
{
ViewBag.Id = clinicProfile.Id;
if (ModelState.IsValid)
{
if (clinicProfile.Id != 0)
{
// here you want to tell the SharedContext to attach the contactData to the clinicProfile
// you need to retrieve the lastVersion of contactData from db
var currentContactData=SharedContext.Current.ContactData.Single(t=>t.Id=contactData.Id);
// update the changed data in the currentContactData
clinicProfile.ContactData =currentContactData; // instead of contactData;
clinicProfile.AdressData = adressData;
clinicProfile.AdressDataComposed = adressData.ComposeData();
clinicProfile.ContactDataComposed = contactData.ComposeData();
SharedContext.Current.Entry(clinicProfile).State = EntityState.Modified;
SharedContext.Current.SaveChanges();
Config.SaveClinicPhoto(clinicProfile.ClinicImageUpload, clinicProfile.Id);
Config.SaveClinicPreviewPhoto(clinicProfile.ClinicImageUpload, clinicProfile.Id);
return View(new ClinicProfileComposite { AdressData = adressData, ClinicProfile = clinicProfile, ContactData = contactData });
}
{
clinicProfile.ContactData = contactData;
clinicProfile.AdressData = adressData;
clinicProfile.AdressDataComposed = adressData.ComposeData();
clinicProfile.ContactDataComposed = contactData.ComposeData();
SharedContext.Current.Entry(clinicProfile).State = EntityState.Added;
SharedContext.Current.SaveChanges();
Config.SaveClinicPhoto(clinicProfile.ClinicImageUpload, clinicProfile.Id);
Config.SaveClinicPreviewPhoto(clinicProfile.ClinicImageUpload, clinicProfile.Id);
return RedirectToAction("Info", new { id = clinicProfile.Id });
}
}
ViewBag.Id = clinicProfile.Id;
return View(new ClinicProfileComposite { AdressData = adressData, ClinicProfile = clinicProfile, ContactData = contactData });
}
// suite à la discussion des commentaires
si vous souhaitez mettre à jour contactData, vous devez indiquer au contexte que contactData a été modifié en définissant son état sur modifié. Comme vous l'avez mentionné dans votre dernier message, cela fonctionnera si vous procédez comme suit:
SharedContext.Current.Entry (clinicProfile) .State = EntityState.Modified; SharedContext.Current.Entry (contactData) .State = EntityState.Modified; SharedContext.Current.SaveChanges ();
espérons que cela vous aidera
Si vous définissez un nouveau ContactData dans ClinicProfile, vous devez d'abord enregistrer le nouveau ContactData dans la base de données, puis obtenir son nouvel ID et mettre à jour le troisième ClinicProfile avec le nouvel ContactDataId.
clinicProfile.ContactDataId = newContactData.Id;
SharedContext.Current.Entry(clinicProfile).State = EntityState.Modified;
SharedContext.Current.SaveChanges();
si vous souhaitez mettre à jour les propriétés ContactData existantes, vous devez uniquement les enregistrer.
SharedContext.Current.Entry(existingContactData).State = EntityState.Modified;
SharedContext.Current.SaveChanges();