C# 在一个视图中编辑/列出多个模型

C# 在一个视图中编辑/列出多个模型,c#,asp.net-mvc-4,ef-code-first,entity-framework-5,viewmodel,C#,Asp.net Mvc 4,Ef Code First,Entity Framework 5,Viewmodel,我是MVC和EF世界的新手。我的目标是MVC4EF5,首先使用代码 我正在寻找使用一个视图编辑两个相关模型的最佳实践。为简单起见,我有以下两种型号: namespace AddressBook.Models { public class Contact { public int ID { get; set; } public string First_Name { get; set; } public string Last_Nam

我是MVC和EF世界的新手。我的目标是MVC4EF5,首先使用代码

我正在寻找使用一个视图编辑两个相关模型的最佳实践。为简单起见,我有以下两种型号:

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; }
     }
}
在以下情况下:

using System.Data.Entity;
namespace AddressBook.Models
{
    public class DataContext : DbContext
    {
        public DbSet<Contact> Contacts { get; set; }
        public DbSet<PhoneNumber> PhoneNumbers { get; set; }
    }
}
  • 编辑(发布)和编辑(获取)是什么样子

  • 如果能帮我解决这个问题,我将不胜感激

    以下是修改后的编辑(get),以支持联系人没有关联电话号码的情况

    “//获取:/Contact/Edit/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; }
    
    
    }
    
    以及viewmodel

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

    再次感谢您的帮助

    我认为您的视图模型应该如下所示:

    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
        };
    
    好的,试试这个:

    电话号码

    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; }
    }
    
    编辑操作

        [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);
        }
    
    视图

    联系人视图文件夹中
    添加
    编辑模板文件夹
    。然后将一个
    创建强类型PhoneNumber部分视图构建到此文件夹
    ,并将其命名为
    PhoneNumber
    ,与其模型类似

    Scaffold a
    创建强类型联系人视图
    命名
    创建


    然后将
    @Html.EditorFor(model=>model.PhoneNumber)
    添加到主创建视图。

    首先,您需要PhoneNumber中的联系人外键,然后您可以使用自定义保存方法。我会在几分钟内写出来。。。谢谢你的回复。。。当我试图生成scafolding时,我也注意到了外键,它没有自动为我创建viewbag。我现在看到的是“public class PhoneNumber{public int ID{get;set;}public string Number{get;set;}public bool Primary{get;set;}[必需]public int ContactID{get;set;}public Contact联系人{get;set;}}}在我给你写答案之前,还有一个问题,为什么联系人需要有多个号码?这真的有必要吗?@KomengeMwandila:这是我试图理解如何在一个视图中使用多个模型的问题的简化版本。我试图避免用户必须做多篇文章来添加/修改联系人,然后分别添加/修改联系人的主要号码。我知道模型之间的关系是一对多的,我希望它在这个屏幕上表现得像是1对1。但是触点可以有多个数字,仅与一个主触点关联。解决方案在一对一上简单得多,使用一对多,不可能定义触点可能具有的有限数量的对象。只有在创建联系人后,才能在单独的视图中执行此操作。如果你需要一对一的回答,我可以帮你。嗨,库克。。。谢谢你的回复。。。我认为,通过指定edit[HttpPost]来更新,编辑(得到)将是什么这不是我必须将模型与ViewModel关联的地方吗?这是一个标准的投影查询新建ContactPrimaryNumberViewModel的实例我昨晚开始的路径这是我使用的“var ContactPrimaryNumber=from pn in db.phoneNumber where pn.ContactID==id&&pn.Primary==true选择新建”{ContactID=pn.ContactID,First_Name=pn.Contact.First_Name,Last_Name=pn.Contact.Last_Name,Number=pn.Number}“但是我遇到了一个错误:无法隐式转换类型”System.Linq.IQueryable“我想我理解这个错误,我正试图将投影创建的注释性类型分配给我的veiwmodel类型。但是我不知道如何修复它。啊哈……现在我明白了为什么每个人都说在视图中使用viewmodel而不是entitymodel到目前为止,我已经在实体模型上使用了注释,当您第一次说在viewmodel上使用dataannotations时,我想我会在viewmodel上复制逻辑,但我认为属性应该只在viewmodel的一个位置。我现在正在尝试好的,我已经让它从n到n工作了…非常感谢您r如果有人需要帮助,我将发布整个解决方案same@KomengeMwadila:谢谢……我正在试now@KomengeMwadila:我已跟踪您在新创建的EditorTemplates文件夹中创建部分视图。在“联系人视图名称创建”中丢失了我的信息我应该将此视图添加到何处?此视图是否与创建/编辑/…视图中的视图不同generation@KomengeMwadila:当我添加@Html.EditorFor(model=>model.PhoneNumber)时对于Contact的Create视图,它正确地声明PhoneNumber不是传递给的模型的一部分it@user2129585
    联系人视图
    将是母版页,因此它将自动被称为
    创建
    。这一切都取决于您传递给联系人视图的模型。@KomengeMwadila:我们正在传递联系人模型上面的编辑(获取)代码。
    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; }
    }
    
    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);
        }