1

我是MVC和EF世界的新手。我首先使用代碼針對MVC 4 EF 5。在一個視圖中編輯/列出多個模型

我正在尋找使用一個視圖編輯兩個相關模型的最佳做法。爲了簡單起見,我有以下兩種模式:

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<PhoneNumber> PhoneNumbers { get; set; } 
    } 
} 

namespace AddressBook.Models 
{ 
    public class PhoneNumber 
    { 
     public int ID { get; set; } 
     public string Number { get; set; } 
     public bool Primary { get; set; } 
    } 
} 

有以下方面:

using System.Data.Entity; 
namespace AddressBook.Models 
{ 
    public class DataContext : DbContext 
    { 
     public DbSet<Contact> Contacts { get; set; } 
     public DbSet<PhoneNumber> PhoneNumbers { get; set; } 
    } 
} 

的聯繫和PhoneNumber之間的關係是一對多的,不過我想要在Primary設置爲true時能夠編輯first_name,last_name和Number,所以我們將僅編輯每個聯繫人記錄的一個電話號碼。

我看過類似的帖子指向使用ViewModel,但我所看到的viewmodels的唯一例子是在傳遞下拉信息時使用而不是viewbag。

我想我有幾個問題:

  1. 將視圖模型看起來像下面?

    public class ContactPrimaryNumberViewModel 
    { 
        public Contact ContactToEdit {get; set;} 
        public PhoneNumber PhoneNumberToEdit {get;set;} 
    } 
    
  2. 什麼是編輯(後)和編輯(get)的樣子?

任何幫助,將不勝感激幫助我滿腦子都在這...

這裏編輯(GET)修改爲支持,如果聯繫人沒有電話號碼相關聯

'// GET:/聯繫人/編輯/ 5

public ActionResult Edit(int id = 0) 
    { 
     ContactPrimaryNumberViewModel ContactPrimaryNumber = (from pn in db.PhoneNumbers 
                   where pn.ContactID == id && 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); 
    }' 

所以最終大家的解決方案後,幫助:

型號:

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<PhoneNumber> PhoneNumbers { get; set; } 


} 

但是控制器編輯(get和post )

 // 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 => 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 => x.ContactID == ContactPrimaryNumber.ContactID && 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); 
    } 

和視圖模型

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; } 


} 
再次

感謝您的幫助

+0

首先,您需要PhoneNumber中的聯繫人外鍵,然後才能擁有自定義保存方法。我會寫在幾個 – Komengem

+0

嗨Komenge ...感謝您的答覆...我只注意到外鍵也當我試圖生成scafolding和它沒有創造viewbag我automaticaly看起來像現在這樣「公共類******中國 { 公衆詮釋ID {獲得;組; } public string Number {get;組; } public bool Primary {get;組; } [必須] public int ContactID {get;組; } public Contact {get;組; } }」 – user2129585

+0

MHMM一個問題之前,我給你寫我的回答,爲什麼接觸需要有多個號碼?它真的有必要嗎? – Komengem

回答

0

我覺得你的視圖模型應該是這樣的:

public class ContactPrimaryNumberViewModel 
{ 
    public int ID { get; set; } 
    public string First_Name { get; set; } 
    public string Last_Name { get; set; } 
    public string Number { get; set; } 
} 

而且您的更新將如下如:

Contact c = context.Contacts.Find(id); 
PhoneNumber p = context.PhoneNumbers 
    .FirstOrDefault(x => x.id == id && x.Primary == true); 
//validate input 
//update as necessary 
//SaveChanges() etc... 

從您的評論 - 你新建立模型類ContactPrimaryNumberViewModel

var ContactPrimaryNumber = 
    from pn in db.PhoneNumbers 
    where pn.ContactID == id && pn.Primary == true 
    select new ContactPrimaryNumberViewModel() { 
     ContactID = pn.ContactID, 
     First_Name = pn.Contact.First_Name, 
     Last_Name = pn.Contact.Last_Name, 
     Number = pn.Number 
    }; 
+0

嗨qujck ...謝謝爲您的答覆...我認爲通過更新您指定的編輯[HttpPost]編輯(get)看起來像不是,我必須將我的模型與視圖模型 – user2129585

+0

這是一個標準的投影查詢新的ContactPrimaryNumberViewModel實例 – qujck

+0

,這是我開始繼續昨夜的路徑是什麼,我使用風險價值ContactPrimaryNumber從PN =在db.PhoneNumbers其中pn.ContactID == ID && pn.Primary ==真選擇新{=的ContactID pn.ContactID的FIRST_NAME = pn.Contact.First_Name,Last_Name = pn.Contact.Last_Name,Number = pn.Number};'但是我得到一個錯誤:**不能隱式轉換類型'System.Linq.IQueryable '**我想我明白我想要分配一個由投影創建的annotype類型給我的veiwmodel類型的錯誤。但是我不知道該怎麼做才能修復它。 – user2129585

0

好了,試試這個:

******中國

public class PhoneNumber 
{ 
    [Key] 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public int Id { get; set; } 
    public string Number { get; set; } 
    public bool Primary { get; set; } 

    [ForeignKey("Contact"), DatabaseGenerated(DatabaseGeneratedOption.None)] 
    public int? ContactId { get; set; } 

    public virtual Contact Contact { get; set; } 
} 

聯繫

public class Contact 
{ 
    [Key] 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public int ContactId { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public List<PhoneNumber> PhoneNumbers { get; set; } 
} 

SaveContact:這取決於你如何設置你的資料庫或EF類。這可以放在你的EfRepository實現或你的EfDb類中。

public void SavePlayer(Contact contact) 
    { 
     using (var context = new EfDb()) 
     {     
      if (contact.ContactId == 0) 
      {      
       context.Contacts.Add(contact); 
      } 
      else if (contact.ContactId > 0) 
      { 
       var currentContact = context.Contacts 
        .Include(c => c.PhoneNumber) 
        .Single(c => c.ContactId== contact.ContactId); 

       context.Entry(currentContact).CurrentValues.SetValues(contact); 
       currentContact.PhoneNumber= contact.PhoneNumber; 
      } 
      context.SaveChanges(); 
     } 
    } 

編輯操作

[HttpGet] 
    public ActionResult Edit(int id) 
    { 
     var contact= _dataSource.Contacts.FirstOrDefault(c => c.Id == id); 

     return View(player); 
    } 

    [HttpPost] 
    public ActionResult Edit(Contact contact) 
    { 
     try 
     { 
      if (ModelState.IsValid) 
      { 
       _dataSource.SaveContact(contact); 
       return RedirectToAction("About", "Home"); 
      } 
     } 
     catch (Exception) 
     { 
      ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator."); 
     }    
     return View(contact); 
    } 

查看

在你Contact View Folder添加EditorTemplates folder。然後腳手架一個Create Strongly Typed PhoneNumber Partial View to this folder並將其命名爲PhoneNumber就像它的型號。

腳手架一個Create Strongly Typed Contact View命名爲Create

然後加入@Html.EditorFor(model => model.PhoneNumber)到主創建視圖。

+0

@KomengeMwadila:謝謝.. 。我現在正在嘗試 – user2129585

+0

@KomengeMwadila:我跟着你在新創建的EditorTemplates文件夾中創建了部分視圖。我在「聯繫人視圖名稱創建」中失去了我在哪裏添加此視圖是不一樣的創建/編輯/ ...我已經從scafolding一代 – user2129585

+0

@KomengeMwadila:當我添加@ Html.EditorFor( model => model.PhoneNumber)添加到創建聯繫人視圖時,它正確地指出PhoneNumber不是傳遞給它的模型的一部分 – user2129585

相關問題