尝试使用标识列添加新条目时,EF6 引发并发异常

Posted

技术标签:

【中文标题】尝试使用标识列添加新条目时,EF6 引发并发异常【英文标题】:EF6 throws concurrency exception when trying to add new entry with identity column 【发布时间】:2021-11-04 15:33:13 【问题描述】:

我正在使用 EF6 从我的数据库中生成实体模型。我创建了两个测试表。一个表有一个标识列,而另一个表没有。以下是表格:

CREATE TABLE [dbo].[TestNoIdentity] 
(
    [ID]      INT          NOT NULL,
    [DTStamp] DATETIME     NOT NULL,
    [Note]    VARCHAR(255) NULL,

    PRIMARY KEY CLUSTERED ([ID] ASC, [DTStamp] ASC)
);

CREATE TABLE [dbo].[TestIdentity] 
(
    [ID]      INT IDENTITY (1, 1) NOT NULL,
    [DTStamp] DATETIME     NOT NULL,
    [Note]    VARCHAR(255) NULL,

    PRIMARY KEY CLUSTERED ([ID] ASC, [DTStamp] ASC)
);

测试代码:

using (TestEntities entities = new TestEntities())

    // This works
    var entry1 = new TestNoIdentity();
    entry1.ID = 1;
    entry1.DTStamp = DateTime.Now;
    entry1.Note = "No Identity";
    entities.TestNoIdentity.Add(entry1);
    entities.SaveChanges();

    // This doesn't work
    var entry2 = new TestIdentity();
    entry2.DTStamp = DateTime.Now;
    entities.TestIdentity.Add(entry2);
    entities.SaveChanges();     //optimistic concurrency exception
    
    // This query works
    // entities.Database.ExecuteSqlCommand("INSERT INTO [dbo].[TestIdentity] ([DTStamp]) VALUES ('1/1/2021 12:00:00 PM')");
    
    return entities.ID.ToString();

为什么会抛出并发异常?没有其他用户或实体的重复实例。

来自异常的消息:

存储更新、插入或删除语句影响了意外数量的行 (0)。自加载实体后,实体可能已被修改或删除。

【问题讨论】:

请查看此帖:***.com/questions/1836173/… @José Polanco 嗨,我已经检查了该帖子和其他几个相关主题。我可以使用 DbContext.Database.ExecuteSqlCommand() 更新表,并且除了标识列之外具有相同属性的其他表可以毫无问题地更新。当没有其他代码修改实体/数据库时,我无法弄清楚它抛出并发异常的原因。 【参考方案1】:

没有 IDENTITY EF 不必取回 ID,这就是它失败的地方。您的 PK 中有一个 DATETIME 列,而 DATETIME 只有大约 3ms 的精度,因此将存储的值与生成的值进行比较可能会失败。将其更改为 DATETIME2 以更好地匹配 .NET 的 DateTime 的精度,或者将您的 .NET DateTime 修整到最接近的秒数。

【讨论】:

谢谢。这样就解决了问题。我将 DTstamp 切换为字符串,它可以工作。

以上是关于尝试使用标识列添加新条目时,EF6 引发并发异常的主要内容,如果未能解决你的问题,请参考以下文章

在 Firebase 中使用 push() 时如何提取唯一 ID

无法更新标识列“索引”。 EF核心

当我输入超过列长度的数据时,它不会在 ASP.NET 中引发异常

使用 C# 出现错误“无法在表中插入标识列的显式值”

在 Spring Security 中添加新用户时出现异常

创建动态表以使用按钮添加新条目