我是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);
}
和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; }
}
再次感谢您的帮助
答案 0 :(得分: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
};
答案 1 :(得分: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)
添加到主创建视图。