【发布时间】:2013-04-06 06:36:01
【问题描述】:
我是 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; }
}
}
Contact 和 PhoneNumber 之间的关系是一对多的,但是我希望能够在 Primary 设置为 true 时编辑 first_name、last_name 和 Number,因此我们将只编辑每个联系人记录的一个电话号码.
我看到过类似的帖子指向使用 ViewModel,但我看到的唯一示例是在传递下拉信息时使用而不是 viewbag。
我想我有几个问题:
-
ViewModel 会像下面这样吗?
public class ContactPrimaryNumberViewModel { public Contact ContactToEdit {get; set;} public PhoneNumber PhoneNumberToEdit {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; }
}
控制器编辑(获取和发布)
// 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; }
}
再次感谢您的帮助
【问题讨论】:
-
首先你需要一个电话号码中的联系人外键,然后你可以有一个自定义的保存方法。一会儿我会写出来
-
嗨 Komenge ...感谢您的回复...当我尝试生成脚手架时我也注意到了外键并且它没有为我自动创建视图包现在看起来像这样'公共课PhoneNumber { public int ID { get;放; } 公共字符串号码 { 获取;放; } 公共布尔主要 { 获取;放; } [必需] public int ContactID { get;放; } 公共联系人联系人 { 获取;放; } }'
-
Mhmm 在我给你写答案之前还有一个问题,为什么联系人需要有多个号码?真的有必要吗?
-
@KomengeMwandila:这是我试图了解如何在一个视图中使用多个模型的问题的简化版本。我试图避免用户必须发布多个帖子来添加/修改联系人,然后单独添加/修改联系人的主要号码。我知道模型之间的关系是一对多的,我希望它在这个屏幕上表现得好像是一对一的。但联系人可以有多个号码,仅关联一个主号码。
-
解决方案在一对一的情况下要简单得多,在一对多的情况下,不可能定义一个联系人可能拥有的有限数量的对象。这只能在已创建联系人之后在单独的视图中实现。如果您需要一对一的答案,我可以提供帮助。
标签: c# asp.net-mvc-4 ef-code-first entity-framework-5 viewmodel