我的表单包含客户端实体属性的子集,我还包含一个隐藏字段,其中包含客户端的ID。客户端实体本身是通过GET Edit操作提供的。
现在我想进行实体更新,但到目前为止我只是在没有先从数据库加载实体的情况下尝试过。因为POST Edit中的客户端对象具有所需的一切。我想只更新数据存储区中实体的那些属性。
我已将我的应用从3.5移植到4.0 RC1,我的代码现在看起来像这样:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Client client)
{
try
{
using (DocInvoiceEntities edmx = new DocInvoiceEntities())
{
if (string.IsNullOrEmpty(client.client_firstname))
ViewData.ModelState.AddModelError("client_firstname", "Firstname!");
if (string.IsNullOrEmpty(client.client_lastname))
ViewData.ModelState.AddModelError("client_lastname", "Lastname!");
// postcode
client.PostCode = (from p in edmx.PostCodes where p.postcode.Equals(client.PostCode.postcode) select p).First();
// check for errors
if (!ViewData.ModelState.IsValid)
throw new InvalidOperationException();
// save changes to datastore
edmx.Clients.Attach(edmx.Clients.Single(c => c.client_id == client.client_id));
edmx.Clients.ApplyCurrentValues(client);
edmx.SaveChanges();
}
return RedirectToAction("Create", "Invoice");
}
catch
{
return View();
}
ApplyCurrentValues()调用抛出此异常: “ObjectContext中的现有对象处于已添加状态。只有在现有对象处于未更改或已修改状态时才能应用更改。”
答案 0 :(得分:1)
如果您通过您的EntityKey Ids发送,只是想保存您发布的值,那么您只需要:
edmx.Clients.Attach(client);
edmx.SaveChanges();
答案 1 :(得分:0)
我不知道这样做的好方法。 看起来它应该是附加编辑对象并保存更改的情况,但框架不能以这种方式工作。
简而言之,SaveChanges魔术仅适用于从您正在使用的上下文创建的实体对象。控制器创建的实体对象不符合条件。
尝试这样的事情(MVC 2和EF 4)
[HttpPost]
public ActionResult Edit(Client clientToEdit)
{
db.Client.Attach(db.Client.Single(c => c.ID == clientToEdit.ID));
db.Client.ApplyCurrentValues(clientToEdit);
db.SaveChanges();
}
它需要一个查询才能更新,但我没有遇到过一个强有力的方法。 d
答案 2 :(得分:0)
您可以像这样使用TryUpdateModel()......
[HttpPost]
public ActionResult Edit(int id, FormCollection collection)
{
using (var context = new DocInvoiceEntities())
{
var client = context.Clients.Single(u => u.ID == id);
if (TryUpdateModel(client))
{
context.SaveChanges();
return RedirectToAction("Index");
}
}
return View();
}