gpt4 book ai didi

c# - 使用 EF 向表中添加新行时违反主键约束

转载 作者:太空狗 更新时间:2023-10-30 00:26:53 25 4
gpt4 key购买 nike

我们的网络应用程序中出现非常间歇性的(比如每隔几周有人提示一次)违反主键约束的情况。我搜索了代码库,甚至在该表中创建任何行的唯一代码如下:

decimal nextDocId = (from d in context.TPM_PROJECTVERSIONDOCS
orderby d.DOCUMENTID descending
select d.DOCUMENTID).Max() + 1;

foreach (TPM_PROJECTVERSIONDOCS doc in documents)
{
TPM_PROJECTVERSIONDOCS newDoc = new TPM_PROJECTVERSIONDOCS();
newDoc.DOCUMENTID = nextDocId;
newDoc.DOCBLOB = doc.DOCBLOB;
newDoc.DOCUMENTNAME = doc.DOCUMENTNAME;
newDoc.FILECONTENTTYPE = doc.FILECONTENTTYPE;
version.TPM_PROJECTVERSIONDOCS.Add(newDoc);
nextDocId++;
}

我们得到的错误是:

ORA-00001: unique constraint (TPMDBO.TPM_PROJECTVERSIONDOCS_PK) violated

这意味着 DOCUMENTID 已被使用。关于造成这种情况的原因,我有一些理论。首先,如果多个人同时添加文档,在设置 nextDocId 和保存上下文之间的某个时间,新文档可能已添加到数据库中。但是,这个时间只有几毫秒,所以我认为对于我们网站获得的少量流量来说这不太可能。

我的第二个理论是 EF 可能进行了某种缓存,并且 nextDocId 返回了一个不再有效的缓存值。

由于这个错误只是偶尔发生,当然只发生在我们的生产服务器上,我没有很好的方法来调试或重现。

我的问题:这最可能的原因是什么?是否有更好的方法来重写这段代码以防止违反主键?我很想为主键使用一个自动递增字段,但不幸的是 Oracle 不支持它们。切换到 UUID 也是一种解决方案,但会导致大量数据库更改。谢谢!

更新:

这是 TPM_PROJECTVERSIONDOCS 实体:

<EntityType Name="TPM_PROJECTVERSIONDOCS">
<Key>
<PropertyRef Name="DOCUMENTID" />
</Key>
<Property Name="DOCUMENTID" Type="decimal" Nullable="false" />
<Property Name="PROJECTID" Type="decimal" Nullable="false" />
<Property Name="VERSIONID" Type="decimal" Nullable="false" />
<Property Name="DOCUMENTNAME" Type="VARCHAR2" Nullable="false" MaxLength="500" />
<Property Name="DOCBLOB" Type="BLOB" Nullable="false" />
<Property Name="FILECONTENTTYPE" Type="VARCHAR2" Nullable="false" MaxLength="80" />
</EntityType>

我不知道有什么方法可以使 DOCUMENTID 默认为一个序列,或者使用 EF 查询一个序列。

最佳答案

既然您使用的是 Oracle,那么您应该使用一个 oracle 序列值。它不会返回重复项!调用 sequence.nextval 而不是你的 max()+1 将解决它。

关于c# - 使用 EF 向表中添加新行时违反主键约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8993929/

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