gpt4 book ai didi

entity-framework - 使用 Entity Framework 删除并重新添加子行时出现重复键异常

转载 作者:行者123 更新时间:2023-12-04 08:44:44 25 4
gpt4 key购买 nike

我正在使用 Entity Framework 为文档及其页面之间的简单父子关系建模。以下代码应该(按此顺序):

  • 对文档进行一些属性更新
  • 删除文档的任何现有页面
  • 插入传递给该方法的新页面列表。

新页面确实具有与删除页面相同的键,因为有一个由文档编号和页码 (1..n) 组成的索引。

此代码有效。但是,当我删除对 SaveChanges 的第一次调用时,它失败了:

System.Data.SqlClient.SqlException: Cannot insert duplicate key row in object 
'dbo.DocPages' with unique index 'IX_DocPages'.

下面是两次调用 SaveChanges 的工作代码:

        Document doc = _docRepository.GetDocumentByRepositoryDocKey(repository.Repository_ID, repositoryDocKey);

if (doc == null) {
doc = new Document();
_docRepository.Add(doc);
}
_fieldSetter.SetDocumentFields(doc, fieldValues);

List<DocPage> pagesToDelete = (from p in doc.DocPages
select p).ToList();

foreach (DocPage page in pagesToDelete) {
_docRepository.DeletePage(page);
}

_docRepository.GetUnitOfWork().SaveChanges(); //IF WE TAKE THIS OUT IT FAILS

int pageNo = 0;
foreach (ConcordanceDatabase.PageFile pageFile in pageList) {
++pageNo;
DocPage newPage = new DocPage();
newPage.PageNumber = pageNo;
newPage.ImageRelativePath = pageFile.Filespec;
doc.DocPages.Add(newPage);
}

_docRepository.GetUnitOfWork().SaveChanges(); //WHY CAN'T THIS BE THE ONLY CALL TO SaveChanges

如果我按原样保留代码,EF 会创建两个事务——一个用于每次调用 SaveChanges。第一个更新文档并删除任何现有页面。第二个事务插入新页面。我检查了 SQL 跟踪,这就是我所看到的。

但是,如果我删除对 SaveChanges 的第一次调用(因为我希望整个事情在单个事务中运行),EF 神秘地根本不执行删除操作,而是只生成插入物?? -- 导致重复键错误。我不认为等待调用 SaveChanges 在这里应该重要吗?

顺便说一下,对 _docRepository.DeletePage(page) 的调用执行 objectContext.DeleteObject(page)。谁能解释这种行为?谢谢。

最佳答案

我认为更可能的解释是 EF 确实进行了删除,但可能是在插入之后进行的,因此您最终会进入无效状态。

不幸的是,您无法对 DbCommands 在数据库中执行的顺序进行低级别控制。

因此您需要两次 SaveChanges() 调用。

一个选项是创建一个包装 TransactionScope。

然后您可以调用 SaveChanges() 两次,这一切都发生在同一个事务中。

参见 this post有关相关技术的更多信息

希望对你有帮助

亚历克斯

关于entity-framework - 使用 Entity Framework 删除并重新添加子行时出现重复键异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1540106/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com