在我的编辑控制器操作中,我发布了要更新的对象。
[HttpPost]
public virtual ActionResult Edit(Case myCase){
var currentDocuments = db.CaseDocuments.Where(p => p.idCase == myCase.idCase);
foreach (CaseDocument docInDB in currentDocuments )
{
var deleteDoc = true;
foreach (CaseDocument docNew in myCase.CaseDocuments )
{
if (docNew.idDocument == docInDB.idDocument)
deleteDoc = false;
}
if (deleteDoc )
db.CaseDocuments.Remove(docInDB);
}
foreach (CaseDocument pc in myCase.CaseDocuments)
{
if (pc.idDocument == 0)
db.CaseDocuments.Add(pc);
else
db.Entry(pc).State = EntityState.Modified;
}
*** **db.Entry(myCase).State = EntityState.Modified;** //THIS LINE
db.SaveChanges();
}
Case
模型的集合为Documents
,它们与案例模型一起发布。
一旦我进入动作,我就可以计算集合中的文档数量,并且可以说有3个。
然后,为了查看是否需要从数据库中删除文档(因为用户从UI中删除了一个文档),我需要以这种方式从数据库中获取该案例的文档:
var currentDocuments = db.CaseDocuments.Where(p => p.idCase == myCase.idCase);
这里开始奇怪的事情:我尽快执行该语句,myCase.Documents
加载了它在数据库中的内容(假设有4个)!所以,我无法比较2个集合(检测文档是否被删除并从db中删除)。
我需要的是在我的Case模型的编辑操作期间,我需要创建/更新/修改其文档。 我是否需要从其他角度看这个?我在做什么是错的?
修改 的 在评论之后,我意识到我将myCase标记为Modified的行是在开头,我想这就是这种行为的原因。
现在,将该行移到db.SaveChanges()之前,解决了这个问题,但在db.Entry(myCase).State = EntityState.Modified;
说“在ObjectStateManager中已经存在一个具有相同键的对象。“
我在这里做错了什么?这段代码看起来很糟糕!
答案 0 :(得分:1)
以这种方式尝试:
[HttpPost]
public virtual ActionResult Edit(Case myCase){
var currentDocumentIds = db.CaseDocuments
.Where(p => p.idCase == myCase.idCase)
.Select(p => p.idDocument);
foreach (int idInDb in currentDocumentsIds.Where(i => !myCase.CaseDocuments
.Any(ci => ci.idDocumnet == i))
{
var docToDelete = new CaseDocument { idDocument = idInDb };
db.CaseDocuments.Remove(docToDelete);
}
foreach (CaseDocument pc in myCase.CaseDocuments)
{
if (pc.idDocument == 0)
db.CaseDocuments.Add(pc);
else
db.Entry(pc).State = EntityState.Modified;
}
db.Entry(myCase).State = EntityState.Modified;
db.SaveChanges();
}
编辑:此代码与您的代码之间的区别在于它如何与现有文档一起使用。它不加载它们 - 它只加载它们的ID。这样您就可以从数据库中保存一些数据传输,但它也可以帮助您避免该异常。从数据库加载文档时,您已将文档附加到上下文中,但如果您尝试调用它:
db.Entry(pc).State = EntityState.Modified;
您将尝试使用相同的键将文档的另一个实例附加到上下文。这是不允许的 - 上下文只能附加具有唯一键的单个实例。