CREATE UNIQUE INDEX 语句终止,因为发现重复键 EF
The CREATE UNIQUE INDEX statement terminated because a duplicate key was found EF
我正在使用 Entity Framework 和 C# 构建一个应用程序,在我的一个 table 中,我注意到我将主键列命名为与外键列相同的名称即 dbo.MembershipTypes
table 的主键在“MembershipTypeId”属性 上,并且与之有关系的 dbo.Customers
table 在“MembershipTypeId”上有一个外键" 属性 即 public MembershipType MembershipTypeId { get; set; })
。
这引起了问题,所以我将 MembershipTypeId
重命名回 Id
(最初是 Id
,但该列不是标识列,EF 拒绝创建它一个甚至在使用 [DatabaseGenereated(DatabaseGeneratedOption.Identity)]
和 [Key]
属性之后)。
我正在使用代码优先迁移,所以当我尝试使用
恢复更改时
update-database -TargetMigration:(migration before mistake goes here)
在包管理器控制台中,我收到此错误:
The CREATE UNIQUE INDEX statement terminated because a duplicate key was found for the object name 'dbo.MembershipTypes' and the index name 'PK_dbo.MembershipTypes'. The duplicate key value is (0).
Could not create constraint or index. See previous errors.
这是迁移,当我尝试恢复到数据库的早期版本时它给我错误:
public partial class RenameIdColumnAndMakeItIdentityInMembershipTypeTable : DbMigration
{
public override void Up()
{
DropForeignKey("dbo.Customers", "MembershipTypeId", "dbo.MembershipTypes");
DropPrimaryKey("dbo.MembershipTypes");
AddColumn("dbo.MembershipTypes", "MembershipTypeId", c => c.Byte(nullable: false, identity: true));
AddPrimaryKey("dbo.MembershipTypes", "MembershipTypeId");
AddForeignKey("dbo.Customers", "MembershipTypeId", "dbo.MembershipTypes", "MembershipTypeId", cascadeDelete: true);
DropColumn("dbo.MembershipTypes", "Id");
}
public override void Down()
{
AddColumn("dbo.MembershipTypes", "Id", c => c.Byte(nullable: false));
DropForeignKey("dbo.Customers", "MembershipTypeId", "dbo.MembershipTypes");
DropPrimaryKey("dbo.MembershipTypes");
DropColumn("dbo.MembershipTypes", "MembershipTypeId");
AddPrimaryKey("dbo.MembershipTypes", "Id");
AddForeignKey("dbo.Customers", "MembershipTypeId", "dbo.MembershipTypes", "Id", cascadeDelete: true);
}
}
这是用于创建 table 的 T-SQL 代码 EF。我先用它的属性制作了 table,然后在单独的迁移中用参考数据填充了它。
CREATE TABLE [dbo].[MembershipTypes]
(
[SignUpFee] SMALLINT NOT NULL,
[DurationInMonths] TINYINT NOT NULL,
[DiscountRate] TINYINT NOT NULL,
[Name] NVARCHAR(255) DEFAULT ('') NOT NULL,
[MembershipTypeId] TINYINT IDENTITY (1, 1) NOT NULL,
CONSTRAINT [PK_dbo.MembershipTypes]
PRIMARY KEY CLUSTERED ([MembershipTypeId] ASC)
);
这是用于生成客户的代码 table:
CREATE TABLE [dbo].[Customers]
(
[Id] INT IDENTITY (1, 1) NOT NULL,
[Name] NVARCHAR (255) NOT NULL,
[IsSubscribedToNewsletter] BIT DEFAULT ((0)) NOT NULL,
[MembershipTypeId] TINYINT DEFAULT ((0)) NOT NULL,
[Birthdate] DATETIME NULL,
CONSTRAINT [PK_dbo.Customers]
PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [FK_dbo.Customers_dbo.MembershipTypes_MembershipTypeId]
FOREIGN KEY ([MembershipTypeId]) REFERENCES [dbo].[MembershipTypes] ([MembershipTypeId])
ON DELETE CASCADE
);
GO
CREATE NONCLUSTERED INDEX [IX_MembershipTypeId]
ON [dbo].[Customers]([MembershipTypeId] ASC);
这一切都是在我尝试修复 API 以使用 [HttpPost]
创建新客户时发生的。
请帮助我理解为什么会出现此错误以及如何修复它。另外,请帮助我理解为什么重复键从 0 而不是 1 开始。
在此先感谢您的帮助!
感谢 Gert Arnold 在评论中回答这个问题。
我收到此错误的原因是我迁移的 Down
方法中的 Id
列不是标识列。
我的理解是,由于在关系数据库中通常具有主键的Id
列不能为空,因此在此处插入0,因为这是字节或整数类型的默认值。
在我的 Up
方法中,我将 Id
设置为标识列,但由于默认值 0 已经存在,这造成了冲突,因为数据库现在正在为 Id
从0开始。
这行不通,因为 Id
列是唯一的,不能有重复值。例如,即使您的数据库中有 5 个客户并删除了客户 4,也没有其他客户的 ID 为 4。
希望这对以后的人有所帮助!
我正在使用 Entity Framework 和 C# 构建一个应用程序,在我的一个 table 中,我注意到我将主键列命名为与外键列相同的名称即 dbo.MembershipTypes
table 的主键在“MembershipTypeId”属性 上,并且与之有关系的 dbo.Customers
table 在“MembershipTypeId”上有一个外键" 属性 即 public MembershipType MembershipTypeId { get; set; })
。
这引起了问题,所以我将 MembershipTypeId
重命名回 Id
(最初是 Id
,但该列不是标识列,EF 拒绝创建它一个甚至在使用 [DatabaseGenereated(DatabaseGeneratedOption.Identity)]
和 [Key]
属性之后)。
我正在使用代码优先迁移,所以当我尝试使用
恢复更改时update-database -TargetMigration:(migration before mistake goes here)
在包管理器控制台中,我收到此错误:
The CREATE UNIQUE INDEX statement terminated because a duplicate key was found for the object name 'dbo.MembershipTypes' and the index name 'PK_dbo.MembershipTypes'. The duplicate key value is (0). Could not create constraint or index. See previous errors.
这是迁移,当我尝试恢复到数据库的早期版本时它给我错误:
public partial class RenameIdColumnAndMakeItIdentityInMembershipTypeTable : DbMigration
{
public override void Up()
{
DropForeignKey("dbo.Customers", "MembershipTypeId", "dbo.MembershipTypes");
DropPrimaryKey("dbo.MembershipTypes");
AddColumn("dbo.MembershipTypes", "MembershipTypeId", c => c.Byte(nullable: false, identity: true));
AddPrimaryKey("dbo.MembershipTypes", "MembershipTypeId");
AddForeignKey("dbo.Customers", "MembershipTypeId", "dbo.MembershipTypes", "MembershipTypeId", cascadeDelete: true);
DropColumn("dbo.MembershipTypes", "Id");
}
public override void Down()
{
AddColumn("dbo.MembershipTypes", "Id", c => c.Byte(nullable: false));
DropForeignKey("dbo.Customers", "MembershipTypeId", "dbo.MembershipTypes");
DropPrimaryKey("dbo.MembershipTypes");
DropColumn("dbo.MembershipTypes", "MembershipTypeId");
AddPrimaryKey("dbo.MembershipTypes", "Id");
AddForeignKey("dbo.Customers", "MembershipTypeId", "dbo.MembershipTypes", "Id", cascadeDelete: true);
}
}
这是用于创建 table 的 T-SQL 代码 EF。我先用它的属性制作了 table,然后在单独的迁移中用参考数据填充了它。
CREATE TABLE [dbo].[MembershipTypes]
(
[SignUpFee] SMALLINT NOT NULL,
[DurationInMonths] TINYINT NOT NULL,
[DiscountRate] TINYINT NOT NULL,
[Name] NVARCHAR(255) DEFAULT ('') NOT NULL,
[MembershipTypeId] TINYINT IDENTITY (1, 1) NOT NULL,
CONSTRAINT [PK_dbo.MembershipTypes]
PRIMARY KEY CLUSTERED ([MembershipTypeId] ASC)
);
这是用于生成客户的代码 table:
CREATE TABLE [dbo].[Customers]
(
[Id] INT IDENTITY (1, 1) NOT NULL,
[Name] NVARCHAR (255) NOT NULL,
[IsSubscribedToNewsletter] BIT DEFAULT ((0)) NOT NULL,
[MembershipTypeId] TINYINT DEFAULT ((0)) NOT NULL,
[Birthdate] DATETIME NULL,
CONSTRAINT [PK_dbo.Customers]
PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [FK_dbo.Customers_dbo.MembershipTypes_MembershipTypeId]
FOREIGN KEY ([MembershipTypeId]) REFERENCES [dbo].[MembershipTypes] ([MembershipTypeId])
ON DELETE CASCADE
);
GO
CREATE NONCLUSTERED INDEX [IX_MembershipTypeId]
ON [dbo].[Customers]([MembershipTypeId] ASC);
这一切都是在我尝试修复 API 以使用 [HttpPost]
创建新客户时发生的。
请帮助我理解为什么会出现此错误以及如何修复它。另外,请帮助我理解为什么重复键从 0 而不是 1 开始。
在此先感谢您的帮助!
感谢 Gert Arnold 在评论中回答这个问题。
我收到此错误的原因是我迁移的 Down
方法中的 Id
列不是标识列。
我的理解是,由于在关系数据库中通常具有主键的Id
列不能为空,因此在此处插入0,因为这是字节或整数类型的默认值。
在我的 Up
方法中,我将 Id
设置为标识列,但由于默认值 0 已经存在,这造成了冲突,因为数据库现在正在为 Id
从0开始。
这行不通,因为 Id
列是唯一的,不能有重复值。例如,即使您的数据库中有 5 个客户并删除了客户 4,也没有其他客户的 ID 为 4。
希望这对以后的人有所帮助!