我一直在四处张望,却找不到答案。我在“编辑视图”中使用ViewModel,以便可以为某些下拉列表提供值。现在,当我去更新数据库时,我不明白如何更新数据库记录。我猜想我可以创建一个新的实体对象,执行查找,然后根据从Form传入的ViewModel更新每个属性,但是这似乎需要很多手动工作。
在这里,我在“编辑”视图中使用VeiwModel。
@model CPPCustomerCall.ViewModels.CustomerCallVM
这是我的控制器的ActionResult。我将ActionResult的对象类型更改为采用CustomerCallVM,而不是自动生成的CustomerCall。我假设因为“编辑视图”的模型是ViewModel,所以它是ActionResult将接收的对象的类型。但是,我的ViewModel具有更多实体模型不需要的属性来更新记录。如何在此ActionResult中更新数据库记录?
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit([Bind(Include = "Id,CustomerName,Subject,PhoneNumber,CallMessage,CallDate,Status,CallNotes")] CustomerCallVM customerCall)
{
if (ModelState.IsValid)
{
db.Entry(customerCall).State = EntityState.Modified;
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
return View(customerCall);
}
首先,Bind
视图模型是互斥的。如果您不希望对某些内容进行修改,那么它就不应该放在您的视图模型中。除非视图模型无法直接保存,否则它们会与实体有所不同。结果,您的零件上总会存在一些干预,以将发布的值映射回实体,这意味着您可以有选择地不映射某些不应该存在的属性,无论它们是否已发布。简而言之,摆脱掉那些Bind
东西。这只是需要维护的其他内容,并且是大量潜在错误的来源。
也就是说,您拥有的代码是可行的;您只是缺少了将数据从视图模型映射回实体的关键部分。首先,您需要从数据库中获取实体,以便有一个可以使用的基础:
var customerCall = db.CustomerCalls.Find(id);
if (customerCall == null)
{
return new HttpNotFoundResult();
}
FWIW,根据REST约定,您的编辑路径应在路径中包含ID。并非严格要求遵循REST,但是肯定会建议这样做。虽然坚持使用REST的Web应用程序并不意味着它是一个好的应用程序,但是不坚持使用其余部分通常是设计和编码程序设计错误的肯定迹象。
然后,您在属性上进行映射。您可以手动执行以下操作:
customerCall.CustomerName = model.CustomerName;
// etc.
或者,您可以使用AutoMapper之类的库。
mapper.Map(model, customerCall);
当然,AutoMapper需要一些初始设置才能使此魔术正常工作,因此,如果您要采用这种方法,请查阅文档。手动映射更容易,但更繁琐且重复。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句