title: Editing/Listing multiple models within one view
body: <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>