How to Edit and Save ViewModels data back to database
asp.net-mvc, asp.net-mvc-4, entity-framework
Solution
First of all, it's really good that you are using `ViewModels` but for this particular case, it's probably not necessary, your `Create` view could look like this:
@model MvcApplication1.Models.Doctor
//other fields here
<div class="editor-label">
@Html.LabelFor(model => model.DoctorAddress.Address)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.DoctorAddress.Address)
@Html.ValidationMessageFor(model => model.DoctorAddress.Address)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.DoctorCharge.IPDCharge)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.DoctorCharge.IPDCharge)
@Html.ValidationMessageFor(model => model.DoctorCharge.IPDCharge)
</div>
//other fields here
Then your `Doctor` controller:
[HttpPost]
public ActionResult Create(Doctor doctor)
{
if (ModelState.IsValid)
{
db.Doctors.Add(doctor);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(doctor);
}
Your `Edit` action could then look like this:
[HttpGet]
public ActionResult Edit(int id = 0)
{
Doctor doctor = db.Doctors.Find(id);
if (doctor == null)
{
return HttpNotFound();
}
return View(doctor);
}
[HttpPost]
public ActionResult Edit(Doctor doctor)
{
if (ModelState.IsValid)
{
db.Entry(doctor).State = EntityState.Modified;
db.Entry(doctor.DoctorAddress).State = EntityState.Modified;
db.Entry(doctor.DoctorCharge).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(doctor);
}
If you want to keep your ViewModel then it could look like this:
[HttpPost]
public ActionResult Edit(DoctorViewModel doctorViewModel)
{
if (ModelState.IsValid)
{
var doctorAddress = doctorViewModel.DoctorAddress;
var doctorCharge = doctorViewModel.DoctorCharge;
var doctor = doctorViewModel.Doctor;
db.Entry(doctorAddress).State = EntityState.Modified;
db.Entry(doctorCharge).State = EntityState.Modified;
db.Entry(doctor).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(doctor);
}
Problem
I have a ViewModel which is joined by three Entities to get data from all entities into one view form. Although i succeeded to implement the same. But i have no idea how to Edit and Save data back to the database. My model classes are joined by one to one relationship. My Models are: ``` public class Doctor { public int DoctorId { get; set; } public string Name { get; set; } public string Speciality { get; set; } public virtual DoctorAddress DoctorAddress { get; set; } public virtual DoctorCharge DoctorCharge { get; set; } public virtual DoctorAvailablity DoctorAvailablity { get; set; } } public class DoctorAddress { public string Address { get; set; } public string City { get; set; } public int DoctorId { get; set; } public virtual Doctor Doctor { get; set; } } public class DoctorCharge { public decimal OPDCharge { get; set; } public decimal IPDCharge { get; set; } public int DoctorId { get; set; } public virtual Doctor Doctor { get; set; } } ``` My ViewModel is: ``` public class DoctorViewModel { public Doctor Doctor { get; set; } public DoctorAddress DoctorAddress { get; set; } public DoctorCharge DoctorCharge { get; set; } } ``` My Controller is: ``` public ActionResult Index() { var model = from t1 in db.Doctors join d in db.DoctorAddress on t1.DoctorId equals d.DoctorId into listi join dc in db.DoctorCharges on t1.DoctorId equals dc.DoctorId into listj from d in listi.DefaultIfEmpty() from dc in listj.DefaultIfEmpty() select new DoctorDetailsViewModel.DoctorViewModel { Doctor = t1, DoctorAddress = d, DoctorCharge = dc }; return View(model.ToList()); } ``` My View is: ``` @model XXX.DoctorDetailsViewModel.DoctorViewModel @using (Html.BeginForm()) { @Html.ValidationSummary(true) <fieldset> <legend>Doctor</legend> <div class="editor-label"> Name </div> <div class="editor-field"> @Html.EditorFor(model => model.Doctor.Name) </div> <div class="editor-label"> OPD Charge </div> <div class="editor-field"> @Html.EditorFor(model => model.DoctorCharge.OPDCharge) </div> <div class="editor-label"> Address </div> <div class="editor-field"> @Html.EditorFor(model => model.DoctorAddress.Address) </div> <p> <input type="submit" value="Create" /> </p> </fieldset>} ``` My Controller Class is: ``` public ActionResult Create() { return View(); } // // POST: /Doctor/Create [HttpPost] public ActionResult Create(Doctor doctor) { if (ModelState.IsValid) { db.Doctors.Add(doctor); db.SaveChanges(); return RedirectToAction("Index"); } return View(doctor); } ``` Please help me how do i do. Thanks in advance.