我以前从未见过这种情况,很奇怪。
我有一个针对的本地SQL Server 2012 Express数据库。使用TestDrive插件运行简单的测试套件,并使用EF v5访问数据库。
我只是运行了一个将记录插入数据库的测试。我的表中有9行,其ID为1-9。下一个插入和ID恰好跳了10000 !!!!
Id列为:
1, 2, 3, 4, 5, 6, 7, 8, 9, 10009
我知道插入失败也会增加ID,但我可以保证在测试运行之间的5秒内没有10,000次插入失败…
该表的结构真的很简单,有一堆列和一个自动递增,类型bigint(长)的标识列,没有SP,触发器或任何其他编程内容。
bigint
[Id] [bigint] IDENTITY(1,1) NOT NULL,
非常令人困惑,还有其他人看到过这种情况吗?
这篇博客文章还有一些其他细节。看起来像在2012年,identity是作为一个序列实现的。默认情况下,序列具有缓存。如果缓存丢失,则会丢失缓存中的序列值。
identity
建议的解决方案是使用以下命令创建一个序列no cache:
no cache
CREATE SEQUENCE TEST_Sequence AS INT START WITH 1 INCREMENT BY 1 NO CACHE
据我所知,标识列后面的序列是不可见的。您不能更改其属性以禁用缓存。
要将其与Entity Framework一起使用,可以将主键设置StoredGeneratedPattern为Computed。然后,您可以在instead of insert触发器中生成身份服务器端:
StoredGeneratedPattern
Computed
instead of insert
if exists (select * from sys.sequences where name = 'Sequence1') drop sequence Sequence1 if exists (select * from sys.tables where name = 'Table1') drop table Table1 if exists (select * from sys.triggers where name = 'Trigger1') drop trigger Trigger1 go create sequence Sequence1 as int start with 1 increment by 1 no cache go create table Table1 ( id int primary key, col1 varchar(50) ) go create trigger Trigger1 on Table1 instead of insert as insert Table1 (ID, col1) select next value for Sequence1 , col1 from inserted go insert Table1 (col1) values ('row1'); insert Table1 (col1) values ('row2'); insert Table1 (col1) values ('row3'); select * from Table1
如果您找到更好的解决方案,请告诉我:)