我已经把头发撕成了几天,在我完全秃顶之前,是时候问所有比我更聪明的人如何做到这一点。
我正在使用Entity Framework 4和Code First CTP 5和MVC 3。
现在的异常消息是“ObjectStateManager中已存在具有相同键的对象.ObjectStateManager无法使用相同的键跟踪多个对象。”
首先是编辑表单发布到的控制器:
public ActionResult Save(ClientEntity postedClient)
{
try
{
if (ModelState.IsValid)
{
Base.clientInterface.Save(postedClient);
return RedirectToAction("Index");
}
}
catch (Exception)
{
throw;
}
SetupManageData(null, postedClient);
return View("Manage");
}
客户端界面上的Save方法是:
public void Save(ClientEntity theClient)
{
SetContext();
if (theClient.clientId == 0)
this.pContext.Clients.Add(theClient);
else
{
ClientEntity existingClient = GetSingle(theClient.clientId); // Get the existing entity from the data store.
// PseudoCode: Merge existingClient and theClient - Can this be done without using ObjectStateManager?
// PseudoCode: Attach merged entity to context so that SaveChanges will update it in the database - is this correct?
}
this.pContext.SaveChanges();
}
private void SetContext()
{
if (this.pContext == null)
this.pContext = new PersistanceContext();
}
Persistance上下文是DBContext,如下所示:
public class PersistanceContext : DbContext
{
public DbSet<ClientEntity> Clients { get; set; }
}
答案 0 :(得分:0)
这应该有用。
if (theClient.clientId == 0)
{
this.pContext.Clients.Add(theClient);
}
else
{
ClientEntity existingClient = this.pContext.Clients.Single(o => o.ClientId == theClient.ClientId);
// map properties
existingClient.Name = theClient.name;
// ....
}
this.pContext.SaveChanges();
[编辑]
更容易(恕我直言)分割创作&amp;将对象编辑为2个单独的视图并避免使用TryUpdateModel的属性映射。
[HttpPost]
public ViewResult Edit(int clientID, FormCollection collection)
{
var client = pContext.Clients.SingleOrDefault(o => o.ID == clientID);
if(!TryUpdateModel(client, collection))
{
ViewBag.UpdateError = "Update Failure";
}
else
{
db.SubmitChanges();
}
return View("Details", client);
}
[HttpPost]
public ViewResult Create(FormCollection collection)
{
var client = new Client();
if(!TryUpdateModel(client, collection))
{
ViewBag.UpdateError = "Create Failure";
}
else
{
db.Clients.Add(client);
db.SubmitChanges();
}
return View("Details", client);
}
答案 1 :(得分:0)
clientInterface的生活方式是什么?它是一个单独的东西还是让它在多个请求中保持活着的东西?
我的猜测是它拥有一个数据库上下文的实例,用于获取GET请求中的实体,当POST尝试(重新)将一个客户端实体添加到上下文时,旧的实体仍然存在他们发生冲突。
尝试使用每个请求销毁clientInterface后面的对象。也许使用支持per-webrequest生活方式的DI容器,这样你就不用担心了。
我希望我的猜测是正确的,这是有帮助的。