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

相关问题