我正在做我的第一个ASP.NETMVC(beta for version 3)应用程序(使用EF4)和一些关于保存新记录和更新现有记录的约定有点困难。我用的是标准路线图。
当用户转到页面/会话/评估时,他们可以输入新记录并保存。我有一个定义如下的动作:
[ActionName("Evaluate")]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EvaluateSave(EvaluteSessionViewModel evaluatedSession)
{
}
当他们保存时,我从视图模型中抓取一个实体并将其附加到我的上下文并保存。到目前为止,还不错。现在我希望用户能够通过url/session/Evaluate/1编辑此记录,其中“1”是记录ID。
编辑:我将EF实体作为属性附加到视图模型。
如果我添加像这样的重载方法(这样我就可以自动检索“1”部分)。
[ActionName("Evaluate")]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EvaluateSave(ID, EvaluteSessionViewModel evaluatedSession)
{
}
我想做的是:
// Load the original entity from EF
// Rebind the postback so that the values posted update the entity
// Save the result
所以看来我不得不手动检查每个字段,看它是否已更改,如果有,请更新它。像这样:
if (evaluatedSession.MyEntity.myField <> savedSession.myField)
savedSession.myField = evaluatedSession.MyEntity.myField;
或者,保存实体的副本,并确保所有不可编辑的实体都没有更改。讨厌。
所以有两个问题:
第一:如何消除重载方法的歧义?
第二:有没有更好的方法来处理更新以前保存的记录?
编辑:我想我可以用一些类似Automapper的东西。。。
编辑9/22/2010-好的,看起来这应该是两个项目的组合:您可以通过类级别的[bind(exclude=“field1,field2”)]属性来控制绑定哪些字段(特别是排除其中一些字段),或者作为保存方法的一部分,例如。
public ActionResult EvaluateSave([Bind(Exclude="field1")] EvaluateSessionViewModel evaluatedSession)
在EF方面,您应该能够从上下文中使用ApplyCurrentValues()方法,例如。
context.ApplyCurrentValues(savedEval.EntityKey.EntitySetName, evaluatedSession);
当然,这对我来说似乎不管用。我一直得到“在ObjectStateManager中找不到具有与所提供对象的键匹配的键的对象。验证所提供对象的键值是否与必须应用更改的对象的键值匹配。“。
context.AttachTo(savedEval.EntityKey.EntitySetName, savedEval);
它还是失败了。我猜这和MVC创建的EF实体对象的类型有关(也许它的填充不够让EF4做任何事情?)。我原本希望.NET framework stepping能够遍历它,看看它试图做什么,但看来EF4并不是交易的一部分。我用反光镜看了看,但对我来说想象发生了什么有点困难。