Note that there are some explanatory texts on larger screens.

plurals
  1. POEditing/Listing multiple models within one view
    primarykey
    data
    text
    <p>I am new to the MVC and EF world. I am targeting MVC 4 EF 5 using code first.</p> <p>I am looking for the best practice for editing two related models using one view. For simplicity I have the following two Models:</p> <pre><code>namespace AddressBook.Models { public class Contact { public int ID { get; set; } public string First_Name { get; set; } public string Last_Name { get; set; } public List&lt;PhoneNumber&gt; PhoneNumbers { get; set; } } } </code></pre> <p>and</p> <pre><code>namespace AddressBook.Models { public class PhoneNumber { public int ID { get; set; } public string Number { get; set; } public bool Primary { get; set; } } } </code></pre> <p>with the following context:</p> <pre><code>using System.Data.Entity; namespace AddressBook.Models { public class DataContext : DbContext { public DbSet&lt;Contact&gt; Contacts { get; set; } public DbSet&lt;PhoneNumber&gt; PhoneNumbers { get; set; } } } </code></pre> <p>The relationship between the Contact and PhoneNumber is one to many, However I would like to be able to edit the first_name, last_name and Number when the Primary is set to true, so we would be editing only one phone number per contact record.</p> <p>I have seen similar posts that point to using a ViewModel but the only examples of viewmodels I have seen are when used instead of the viewbag when passing the information for a dropdown.</p> <p>I guess I have a few questions:</p> <ol> <li><p>would the ViewModel look like below?</p> <pre><code>public class ContactPrimaryNumberViewModel { public Contact ContactToEdit {get; set;} public PhoneNumber PhoneNumberToEdit {get;set;} } </code></pre></li> <li><p>what would the edit(post) and edit(get) look like?</p></li> </ol> <p>Any help would be appreciated to help me wrap my head around this ...</p> <p>here is the Edit(get) modified to support if contact does not have phone number associated</p> <p>' // GET: /Contact/Edit/5</p> <pre><code> public ActionResult Edit(int id = 0) { ContactPrimaryNumberViewModel ContactPrimaryNumber = (from pn in db.PhoneNumbers where pn.ContactID == id &amp;&amp; pn.Primary == true select new ContactPrimaryNumberViewModel { ContactID = pn.ContactID, First_Name = pn.Contact.First_Name, Last_Name = pn.Contact.Last_Name, Number = pn.Number }).SingleOrDefault(); if (ContactPrimaryNumber == null) { ContactPrimaryNumber = (from c in db.Contacts where c.ID == id select new ContactPrimaryNumberViewModel { ContactID = c.ID, First_Name = c.First_Name, Last_Name = c.Last_Name, Number = null }).Single(); } return View(ContactPrimaryNumber); }' </code></pre> <p>so the final solution after everyones help is:</p> <p>the models:</p> <pre><code> public class PhoneNumber { public int ID { get; set; } public string Number { get; set; } public bool Primary { get; set; } [Required] public int ContactID { get; set; } public Contact Contact { get; set; } } public class Contact { public int ID { get; set; } public string First_Name { get; set; } public string Last_Name { get; set; } public List&lt;PhoneNumber&gt; PhoneNumbers { get; set; } } </code></pre> <p>The controler edit(get and post)</p> <pre><code> // GET: /Contact/Edit/5 public ActionResult Edit(int id = 0) { ContactPrimaryNumberViewModel ContactPrimaryNumber = (from c in db.Contacts join pn in db.PhoneNumbers on c.ID equals pn.ContactID into outer from _pn in outer.Where(p =&gt; p.Primary ==true).DefaultIfEmpty() where c.ID == id select new ContactPrimaryNumberViewModel { ContactID = c.ID, First_Name = c.First_Name, Last_Name = c.Last_Name, Number = ((_pn == null) ? "" : _pn.Number) }).FirstOrDefault(); if (ContactPrimaryNumber == null) { return HttpNotFound(); } return View(ContactPrimaryNumber); } // POST: /Contact/Edit/5 [HttpPost] public ActionResult Edit(ContactPrimaryNumberViewModel ContactPrimaryNumber) { Contact c = db.Contacts.Find(ContactPrimaryNumber.ContactID); PhoneNumber pn = db.PhoneNumbers.FirstOrDefault(x =&gt; x.ContactID == ContactPrimaryNumber.ContactID &amp;&amp; x.Primary == true); if (ModelState.IsValid) { c.First_Name = ContactPrimaryNumber.First_Name; c.Last_Name = ContactPrimaryNumber.Last_Name; if (pn == null) //if there is no phone number associated with the contact in the DB { if (!String.IsNullOrEmpty(ContactPrimaryNumber.Number)) { //Add a new phonenumber in the database PhoneNumber Px = new PhoneNumber(); Px.ContactID = ContactPrimaryNumber.ContactID; Px.Number = ContactPrimaryNumber.Number; Px.Primary = true; db.PhoneNumbers.Add(Px); } } else //if there is a phone number associated with the contactin the DB { if (String.IsNullOrEmpty(ContactPrimaryNumber.Number)) { //delete the existing number db.PhoneNumbers.Remove(pn); } else { //modify the existing number pn.Number = ContactPrimaryNumber.Number; } } db.SaveChanges(); return RedirectToAction("Index"); } return View(c); } </code></pre> <p>and the viewmodel</p> <pre><code> public class ContactPrimaryNumberViewModel { public int ContactID { get; set; } public string First_Name { get; set; } public string Last_Name { get; set; } public string Number { get; set; } } </code></pre> <p>thanks again for your help</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload