我一直在四处寻找并且找不到答案。我在编辑视图中使用ViewModel,以便我可以获得某些下拉列表的值。现在当我去更新我的数据库时,我不明白如何更新我的数据库记录。我猜测我可以创建一个新的实体对象,执行查找,然后根据从表单中传入的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);
}
答案 0 :(得分:4)
首先,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需要一些初始设置来完成这项神奇的工作,当然,如果您要走这条路线,请查看文档。手动映射更容易,但更加繁琐和重复。
答案 1 :(得分:0)
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit([Bind(Include = "Id,CustomerName,Subject,PhoneNumber,CallMessage,CallDate,Status,CallNotes")] CustomerCallVM customerCall)
{
if (ModelState.IsValid)
{
// Find The record you need
var dbObj = CustomerCalls.FirstOrDefault(x=> x.id = customerCall.id);
//Check if null
if(dbObj == null) dbObj = new CustomerCall();
/// Map your properties
// Add object to the stack
if(dbObj.id == 0){
CustomerCalls.Add(dbObj);
}else{
CustomerCalls.Update(dbObj);
}
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
return View(customerCall);
}