使用ViewModel和Entity Framework 6更新实体? [英] Update entity with ViewModel and Entity Framework 6?

查看:162
本文介绍了使用ViewModel和Entity Framework 6更新实体?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在环顾四周,找不到答案。我在编辑视图中使用ViewModel,以便我可以为某些下拉列表设置值。现在当我去更新我的数据库时,我不明白我如何更新我的数据库记录。我猜想我可以创建一个新的实体对象,做一个查找,然后根据Form中传入的ViewModel更新每个属性,但这确实好像很多手动工作。



这里我在编辑视图中使用VeiwModel。

  @model CPPCustomerCall.ViewModels.CustomerCallVM 

这是我的控制器的ActionResult。我将ActionResult的对象类型更改为CustomerCallVM,而不是自动生成的CustomerCall。我认为,因为Edit View的模型是ViewModel,它是ActionResult将接收的对象类型。但是,我的ViewModel有更多的属性,实体模型不需要更新记录。如何更新此ActionResult中的DB记录?

  [HttpPost] 
[ValidateAntiForgeryToken]
public async任务< ActionResult>编辑([Bind(Include =Id,CustomerName,Subject,PhoneNumber,CallMessage,CallDate,Status,CallNotes)] CustomerCallVM customerCall)
{
if(ModelState.IsValid)
{
db.Entry(customerCall).State = EntityState.Modified;
等待db.SaveChangesAsync();
return RedirectToAction(Index);
}
return View(customerCall);
}


解决方案

首先,绑定和视图模型是互斥的。如果您不希望有资格被修改,那么它不应该在您的视图模型上,首先。除此之外,视图模型与实体分歧,无法直接保存。因此,您始终会有一些干预措施将贴出的值映射到实体上,这意味着您可以选择性地映射某些属性,而不管它们是否被发布。长和短,摆脱绑定的东西。这只是其他一些维护和潜在错误的巨大来源。



那就是说,你的代码是可行的;您只是错过了将视图模型中的数据映射到您的实体的关键部分。首先,您需要从数据库中获取实体,以便您有一个基础:

  var customerCall = db.CustomerCalls .Find(ID); 
if(customerCall == null)
{
return new HttpNotFoundResult();
}

FWIW,您的编辑路由应包括路由中的ID,根据REST约定。以下REST不是严格要求的,但当然推荐。虽然遵循REST的Web应用程序并不意味着它是一个很好的应用程序,但是不是坚持休息一般是设计和编码不当的应用程序的一个明确标志。



然后,您映射属性。您可以手动执行此操作:

  customerCall.CustomerName = model.CustomerName; 
//等

或者您可以使用像 AutoMapper

  mapper.Map(model, customerCall); 

AutoMapper需要一些初始设置才能使这个神奇的工作,当然,请查看文档,如果你要去那条路线手动映射更简单,但却更加繁琐和重复。


I've been looking around and can't quite find the answer. I'm using a ViewModel in my Edit View so that I can have values for some dropdownlist. Now when I go to update my DB I'm not understanding how I can update my database record. I'm guessing I could create a new entity object, do a Find, and then update each property based on the ViewModel passed in from the Form but that sure seems like a lot of manual work.

Here I'm using the VeiwModel in the Edit View.

@model CPPCustomerCall.ViewModels.CustomerCallVM

Here is my controller's ActionResult. I changed the object type of the ActionResult to take in CustomerCallVM instead of the CustomerCall which was auto-generated. I assume since the Edit View's model is the ViewModel that's the type of object the ActionResult will receive. However, my ViewModel has more properties that aren't needed for the Entity Model to update the record. How do I go about updating my DB record in this 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);
}

解决方案

First, Bind and view models are mutually exclusive. If you don't want something to be eligible to be modified, then it shouldn't be on your view model, in the first place. Barring that, view models diverge from entities in the sense that they can't be saved directly. As a result, there's always some intervention present on your part to map the posted values back onto the entity, which means you can then selectively not map over certain properties that shouldn't be, regardless of whether they were posted or not. Long and short, get rid of the Bind stuff. It's just something else to maintain and a huge source of potential bugs.

That said, the code you have is workable; you're just missing the crucial part where you map the data from your view model back onto your entity. First, you need to fetch the entity from the database so you have a base to work from:

var customerCall = db.CustomerCalls.Find(id);
if (customerCall == null)
{
    return new HttpNotFoundResult();
}

FWIW, your edit route should include the id in the route, according to REST conventions. Following REST isn't strictly required, but it's certainly recommended. While a web application adhering to REST doesn't mean it's a good application, not adhering to rest is generally a sure sign of a badly designed and coded application.

Then, you map over your properties. You can either do this manually:

customerCall.CustomerName = model.CustomerName;
// etc.

Or you can use a library like AutoMapper.

mapper.Map(model, customerCall);

AutoMapper requires a bit of initial setup to make this magic work, of course, so review the docs, if you're going that route. Manual mapping is easier, but far more tedious and repetitive.

这篇关于使用ViewModel和Entity Framework 6更新实体?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆