流利的 NHibernate:"Cannot insert duplicate key in object" 即使 Id 是 GeneratedBy.Native() 或 Identity()

Fluent NHibernate: "Cannot insert duplicate key in object" even though Id is GeneratedBy.Native() or Identity()

我有一个相当简单的 table,带有适当的 Fluent NHibernate 映射,如下所示:

public class Blurb {

    public virtual byte SimpleId { get; set; }
    public virtual string Foo { get; set; }
    public virtual string Bar { get; set; }
}

public class BlurbMap: ClassMap<Blurb> {

    public BlurbMap() {
        Id(x => x.SimpleId).Column("PK_SimpleID").GeneratedBy.Identity();
        Map(x => x.Foo);
        Map(x => x.Bar);
        Table("dbo.SimpleTable");
    }
}

请不要批评我用byte作为ID,数据库是第三方预制的,我无法更改。

我现在想插入一些东西,所以我这样做:

var blurb = new Blurb {
    Foo = "foo",
    Bar = "bar"
};

using(var txn = session.BeginTransaction()) {
    session.SaveOrUpdate(blurb); // <- boom!
    txn.Commit();
}

在我写"boom"的地方,我得到了异常:

could not insert: [Foo.Bar.Blurb][SQL: INSERT INTO dbo.SimpleTable (Foo, Bar) VALUES (?, ?); select SCOPE_IDENTITY()] ---> System.Data.SqlClient.SqlException: Violation of PRIMARY KEY constraint 'PK_SimpleID'. Cannot insert duplicate key in object 'dbo.SimpleTable'. The duplicate key value is (1).

我再次尝试使用 SSMS 插入,我得到了同样的错误,但是随着查询的后续执行,错误消息变成了这样:

The duplicate key value is (1)
The duplicate key value is (2)
The duplicate key value is (3)
...

直到插入成功时按下未使用的键。

我已经尝试 GeneratedBy.Native() 但没有用。目前,我只能想到像

这样的解决方法
var lastBlurb = session.Query<Blurb>().Select(x => x.SimpleId).Max();
newBlurb.SimpleId = lastBlurb + 1;
session.SaveOrUpdate(newBlurb);

这是可行的,因为 "real" table 只包含 10 到 20 个元素,而且只有一个程序对 table 进行写访问(是的,我们真的知道并且可以确定这一点!)但是可能有另一种解决方法吗?还是(外部)数据库设计者做错了什么?

我post这是一个答案,因为它很长。

原来问题完全不同。我 运行 在我的测试数据库中加入了这个。我 运行 我的开发系统上的数据库副本用于集成测试。每次测试后运行,数据库都会被清除并重置为我从第三方收到它时的状态。

在那个重置过程中,我有这个小家伙:

EXEC sp_MSForEachTable "DBCC CHECKIDENT ( '?', RESEED, 0)"

这会将每个标识列的种子设置为 0,因此尝试插入新记录会导致错误。哦!

我现在将其更改为对每个 table 使用正确的值,单独发出 DBCC CHECKIDENT 命令,问题就消失了。

头部 -> 办公桌 -> 砰...