I'm new to Entity Framework and this behavior confuses me:
[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; }
...
}
When inserting the new entity all works fine - ContactData is saved to the table and foreign key assigned:
clinicProfile.ContactData = contactData;
SharedContext.Current.Entry(clinicProfile).State = EntityState.Added;
SharedContext.Current.SaveChanges();
But when I try to update this entity, ContactData don't get an update.
clinicProfile.ContactData = contactData;
SharedContext.Current.Entry(clinicProfile).State = EntityState.Modified;
SharedContext.Current.SaveChanges();
Must I mark ContactData as modified too? Or am I just doing something wrong?
EDIT-2 - The answer
Use this code, if contactData is the new object in the DB, with the new object id.
clinicProfile.ContactData = contactData;
SharedContext.Current.Entry(clinicProfile).State = EntityState.Modified;
SharedContext.Current.SaveChanges();
If you just want to update the old contactData, it would be correct to use this code:
SharedContext.Current.Entry(contactData).State = EntityState.Modified;
SharedContext.Current.SaveChanges();
EDIT - extended code snapshot
Code from MVC controller, postback from the page. Parameters "clinicProfile" and "contactData", "adressData" contain valid Id's.
[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 });
}
you just misplaced the foreign key property
[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; }
...
}
and when you want to set the foreign key data, you can either set the ContactDataId value or retrieve the ContactData from Database as object and set it in the 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 });
}
// as result of comments discussion
if you want to update contactData , you need to tell the context that contactData was modified by setting its state to modified and as you mentioned in your last post, it will work if you make the following:
SharedContext.Current.Entry(clinicProfile).State = EntityState.Modified; SharedContext.Current.Entry(contactData).State = EntityState.Modified; SharedContext.Current.SaveChanges();
hope that this will help you
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With