当我通过 EF Core 更新数据库时创建唯一索引重复键
CREATE UNIQUE INDEX duplicate key when I update-database by EF Core
我在迁移到数据库时遇到错误问题
The CREATE UNIQUE INDEX statement terminated because a duplicate key was found for the object name 'dbo.Cities' and the index name 'IX_Cities_CountryId'. The duplicate key value is (1).
The statement has been terminated.
我为上下文 table 和列配置编写下一个代码:
public class CityConfiguration : IEntityTypeConfiguration<City>
{
public void Configure(EntityTypeBuilder<City> builder)
{
builder.HasKey(x => x.Id).HasName("PK_City_Id");
builder.Property(x => x.Id).ValueGeneratedOnAdd();
builder.HasIndex(x => x.Name).IsUnique().HasName("IX_dbo_Cities_Name");
builder.Property(x => x.Name).HasMaxLength(64)
.IsRequired();
builder.Property(x => x.Region).HasMaxLength(64)
.IsRequired();
builder.Property(x => x.CountryId).IsRequired();
builder.HasOne<Country>(x => x.Country)
.WithOne(x => x.City)
.HasForeignKey<City>(x => x.CountryId);
builder.HasData(InitDefaultCities());
}
private City[] InitDefaultCities()
{
var cities = new City[]
{
new City() { Id = 1, Name = "Atlanta", Region = "Georgia", CountryId = 1, },
new City() { Id = 2, Name = "Boston", Region = "Massachusetts", CountryId = 1 },
new City() { Id = 3, Name = "Brooklyn", Region = "New York", CountryId = 1 },
new City() { Id = 4, Name = "Charlotte", Region = "North Carolina", CountryId = 1 },
new City() { Id = 5, Name = "Chicago", Region = "Illinois", CountryId = 1 },
new City() { Id = 6, Name = "Cleveland", Region = "Ohio", CountryId = 1 },
new City() { Id = 7, Name = "Dallas", Region = "Texas", CountryId = 1 },
new City() { Id = 8, Name = "Denver", Region = "Colorado", CountryId = 1 },
new City() { Id = 9, Name = "Detroit", Region = "Michigan", CountryId = 1 },
new City() { Id = 10, Name = "San Francisco", Region = "California", CountryId = 1 },
new City() { Id = 11, Name = "Houston", Region = "Texas", CountryId = 1 },
new City() { Id = 12, Name = "Indianapolis", Region = "Indiana", CountryId = 1 },
new City() { Id = 13, Name = "Los Angeles", Region = "California", CountryId = 1 },
new City() { Id = 14, Name = "Memphis", Region = "Tennessee", CountryId = 1 },
new City() { Id = 15, Name = "Miami", Region = "Florida", CountryId = 1 },
new City() { Id = 16, Name = "Milwaukee", Region = "Wisconsin", CountryId = 1 },
new City() { Id = 17, Name = "Minneapolis", Region = "Minnesota", CountryId = 1 },
new City() { Id = 18, Name = "New Orlean", Region = "Louisiana", CountryId = 1 },
new City() { Id = 19, Name = "Manhattan", Region = "New York", CountryId = 1 },
new City() { Id = 20, Name = "Oklahoma", Region = "Oklahoma City", CountryId = 1 },
new City() { Id = 21, Name = "Orlando", Region = "Florida", CountryId = 1 },
new City() { Id = 22, Name = "Philadelphia", Region = "Pennsylvania", CountryId = 1 },
new City() { Id = 23, Name = "Phoenix", Region = "Arizona", CountryId = 1 },
new City() { Id = 24, Name = "Portland", Region = "Oregon", CountryId = 1 },
new City() { Id = 25, Name = "Sacramento", Region = "California", CountryId = 1 },
new City() { Id = 26, Name = "San Antonio", Region = "Texas", CountryId = 1 },
new City() { Id = 27, Name = "Toronto", Region = "Ontario", CountryId = 2 },
new City() { Id = 28, Name = "Salt Lake City", Region = "Utah", CountryId = 1 },
new City() { Id = 29, Name = "Washinton D.C.", Region = "Washinton", CountryId = 1 }
};
return cities;
}
}
添加迁移后它转换为
migrationBuilder.CreateTable(
name: "Cities",
schema: "dbo",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Name = table.Column<string>(maxLength: 64, nullable: false),
Region = table.Column<string>(maxLength: 64, nullable: false),
CountryId = table.Column<int>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_City_Id", x => x.Id);
table.ForeignKey(
name: "FK_Cities_Countries_CountryId",
column: x => x.CountryId,
principalSchema: "dbo",
principalTable: "Countries",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.InsertData(
schema: "dbo",
table: "Cities",
columns: new[] { "Id", "CountryId", "Name", "Region" },
values: new object[,]
{
{ 1, 1, "Atlanta", "Georgia" },
{ 28, 1, "Salt Lake City", "Utah" },
{ 26, 1, "San Antonio", "Texas" },
{ 25, 1, "Sacramento", "California" },
{ 24, 1, "Portland", "Oregon" },
{ 23, 1, "Phoenix", "Arizona" },
{ 22, 1, "Philadelphia", "Pennsylvania" },
{ 21, 1, "Orlando", "Florida" },
{ 20, 1, "Oklahoma", "Oklahoma City" },
{ 19, 1, "Manhattan", "New York" },
{ 18, 1, "New Orlean", "Louisiana" },
{ 17, 1, "Minneapolis", "Minnesota" },
{ 16, 1, "Milwaukee", "Wisconsin" },
{ 29, 1, "Washinton D.C.", "Washinton" },
{ 15, 1, "Miami", "Florida" },
{ 13, 1, "Los Angeles", "California" },
{ 12, 1, "Indianapolis", "Indiana" },
{ 11, 1, "Houston", "Texas" },
{ 10, 1, "San Francisco", "California" },
{ 9, 1, "Detroit", "Michigan" },
{ 8, 1, "Denver", "Colorado" },
{ 7, 1, "Dallas", "Texas" },
{ 6, 1, "Cleveland", "Ohio" },
{ 5, 1, "Chicago", "Illinois" },
{ 4, 1, "Charlotte", "North Carolina" },
{ 3, 1, "Brooklyn", "New York" },
{ 2, 1, "Boston", "Massachusetts" },
{ 14, 1, "Memphis", "Tennessee" },
{ 27, 2, "Toronto", "Ontario" }
});
migrationBuilder.CreateIndex(
name: "IX_Cities_CountryId",
schema: "dbo",
table: "Cities",
column: "CountryId",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_dbo_Cities_Name",
schema: "dbo",
table: "Cities",
column: "Name",
unique: true);
找不到哪里麻烦,手写改成SQL脚本。不过数据不是问题,都是独一无二的。如果我评论唯一索引,它将正常工作。之后,我将通过文档
中的脚本检查数据
SELECT
Name,
COUNT(Name)
FROM
dbo.Cities
GROUP BY
Name
HAVING
COUNT(Name) > 1;
结果显示为空!
您正在使用以下代码在列 CountryId
上创建唯一索引:
migrationBuilder.CreateIndex(
name: "IX_Cities_CountryId",
schema: "dbo",
table: "Cities",
column: "CountryId",
unique: true);
由于这不是唯一的,我建议将 unique
设置为 false
。可能是打字错误?
唯一索引是由 EF Core 生成的,因为您在 City
和 Country
之间配置了一对一关系:
builder.HasOne<Country>(x => x.Country)
.WithOne(x => x.City)
.HasForeignKey<City>(x => x.CountryId);
显然这不是数据所要求的 - 这应该是一对多关系(City
有一个 Country
,但 Country
有许多城市)。
因此,将 Country
中的 City
导航 属性 替换为这样的内容
public ICollection<City> Cities { get; set; }
分别
builder.HasOne(x => x.Country)
.WithMany(x => x.Cities)
.HasForeignKey(x => x.CountryId);
并且不要忘记重新生成迁移。
我在迁移到数据库时遇到错误问题
The CREATE UNIQUE INDEX statement terminated because a duplicate key was found for the object name 'dbo.Cities' and the index name 'IX_Cities_CountryId'. The duplicate key value is (1). The statement has been terminated.
我为上下文 table 和列配置编写下一个代码:
public class CityConfiguration : IEntityTypeConfiguration<City>
{
public void Configure(EntityTypeBuilder<City> builder)
{
builder.HasKey(x => x.Id).HasName("PK_City_Id");
builder.Property(x => x.Id).ValueGeneratedOnAdd();
builder.HasIndex(x => x.Name).IsUnique().HasName("IX_dbo_Cities_Name");
builder.Property(x => x.Name).HasMaxLength(64)
.IsRequired();
builder.Property(x => x.Region).HasMaxLength(64)
.IsRequired();
builder.Property(x => x.CountryId).IsRequired();
builder.HasOne<Country>(x => x.Country)
.WithOne(x => x.City)
.HasForeignKey<City>(x => x.CountryId);
builder.HasData(InitDefaultCities());
}
private City[] InitDefaultCities()
{
var cities = new City[]
{
new City() { Id = 1, Name = "Atlanta", Region = "Georgia", CountryId = 1, },
new City() { Id = 2, Name = "Boston", Region = "Massachusetts", CountryId = 1 },
new City() { Id = 3, Name = "Brooklyn", Region = "New York", CountryId = 1 },
new City() { Id = 4, Name = "Charlotte", Region = "North Carolina", CountryId = 1 },
new City() { Id = 5, Name = "Chicago", Region = "Illinois", CountryId = 1 },
new City() { Id = 6, Name = "Cleveland", Region = "Ohio", CountryId = 1 },
new City() { Id = 7, Name = "Dallas", Region = "Texas", CountryId = 1 },
new City() { Id = 8, Name = "Denver", Region = "Colorado", CountryId = 1 },
new City() { Id = 9, Name = "Detroit", Region = "Michigan", CountryId = 1 },
new City() { Id = 10, Name = "San Francisco", Region = "California", CountryId = 1 },
new City() { Id = 11, Name = "Houston", Region = "Texas", CountryId = 1 },
new City() { Id = 12, Name = "Indianapolis", Region = "Indiana", CountryId = 1 },
new City() { Id = 13, Name = "Los Angeles", Region = "California", CountryId = 1 },
new City() { Id = 14, Name = "Memphis", Region = "Tennessee", CountryId = 1 },
new City() { Id = 15, Name = "Miami", Region = "Florida", CountryId = 1 },
new City() { Id = 16, Name = "Milwaukee", Region = "Wisconsin", CountryId = 1 },
new City() { Id = 17, Name = "Minneapolis", Region = "Minnesota", CountryId = 1 },
new City() { Id = 18, Name = "New Orlean", Region = "Louisiana", CountryId = 1 },
new City() { Id = 19, Name = "Manhattan", Region = "New York", CountryId = 1 },
new City() { Id = 20, Name = "Oklahoma", Region = "Oklahoma City", CountryId = 1 },
new City() { Id = 21, Name = "Orlando", Region = "Florida", CountryId = 1 },
new City() { Id = 22, Name = "Philadelphia", Region = "Pennsylvania", CountryId = 1 },
new City() { Id = 23, Name = "Phoenix", Region = "Arizona", CountryId = 1 },
new City() { Id = 24, Name = "Portland", Region = "Oregon", CountryId = 1 },
new City() { Id = 25, Name = "Sacramento", Region = "California", CountryId = 1 },
new City() { Id = 26, Name = "San Antonio", Region = "Texas", CountryId = 1 },
new City() { Id = 27, Name = "Toronto", Region = "Ontario", CountryId = 2 },
new City() { Id = 28, Name = "Salt Lake City", Region = "Utah", CountryId = 1 },
new City() { Id = 29, Name = "Washinton D.C.", Region = "Washinton", CountryId = 1 }
};
return cities;
}
}
添加迁移后它转换为
migrationBuilder.CreateTable(
name: "Cities",
schema: "dbo",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Name = table.Column<string>(maxLength: 64, nullable: false),
Region = table.Column<string>(maxLength: 64, nullable: false),
CountryId = table.Column<int>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_City_Id", x => x.Id);
table.ForeignKey(
name: "FK_Cities_Countries_CountryId",
column: x => x.CountryId,
principalSchema: "dbo",
principalTable: "Countries",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.InsertData(
schema: "dbo",
table: "Cities",
columns: new[] { "Id", "CountryId", "Name", "Region" },
values: new object[,]
{
{ 1, 1, "Atlanta", "Georgia" },
{ 28, 1, "Salt Lake City", "Utah" },
{ 26, 1, "San Antonio", "Texas" },
{ 25, 1, "Sacramento", "California" },
{ 24, 1, "Portland", "Oregon" },
{ 23, 1, "Phoenix", "Arizona" },
{ 22, 1, "Philadelphia", "Pennsylvania" },
{ 21, 1, "Orlando", "Florida" },
{ 20, 1, "Oklahoma", "Oklahoma City" },
{ 19, 1, "Manhattan", "New York" },
{ 18, 1, "New Orlean", "Louisiana" },
{ 17, 1, "Minneapolis", "Minnesota" },
{ 16, 1, "Milwaukee", "Wisconsin" },
{ 29, 1, "Washinton D.C.", "Washinton" },
{ 15, 1, "Miami", "Florida" },
{ 13, 1, "Los Angeles", "California" },
{ 12, 1, "Indianapolis", "Indiana" },
{ 11, 1, "Houston", "Texas" },
{ 10, 1, "San Francisco", "California" },
{ 9, 1, "Detroit", "Michigan" },
{ 8, 1, "Denver", "Colorado" },
{ 7, 1, "Dallas", "Texas" },
{ 6, 1, "Cleveland", "Ohio" },
{ 5, 1, "Chicago", "Illinois" },
{ 4, 1, "Charlotte", "North Carolina" },
{ 3, 1, "Brooklyn", "New York" },
{ 2, 1, "Boston", "Massachusetts" },
{ 14, 1, "Memphis", "Tennessee" },
{ 27, 2, "Toronto", "Ontario" }
});
migrationBuilder.CreateIndex(
name: "IX_Cities_CountryId",
schema: "dbo",
table: "Cities",
column: "CountryId",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_dbo_Cities_Name",
schema: "dbo",
table: "Cities",
column: "Name",
unique: true);
找不到哪里麻烦,手写改成SQL脚本。不过数据不是问题,都是独一无二的。如果我评论唯一索引,它将正常工作。之后,我将通过文档
中的脚本检查数据 SELECT
Name,
COUNT(Name)
FROM
dbo.Cities
GROUP BY
Name
HAVING
COUNT(Name) > 1;
结果显示为空!
您正在使用以下代码在列 CountryId
上创建唯一索引:
migrationBuilder.CreateIndex(
name: "IX_Cities_CountryId",
schema: "dbo",
table: "Cities",
column: "CountryId",
unique: true);
由于这不是唯一的,我建议将 unique
设置为 false
。可能是打字错误?
唯一索引是由 EF Core 生成的,因为您在 City
和 Country
之间配置了一对一关系:
builder.HasOne<Country>(x => x.Country)
.WithOne(x => x.City)
.HasForeignKey<City>(x => x.CountryId);
显然这不是数据所要求的 - 这应该是一对多关系(City
有一个 Country
,但 Country
有许多城市)。
因此,将 Country
中的 City
导航 属性 替换为这样的内容
public ICollection<City> Cities { get; set; }
分别
builder.HasOne(x => x.Country)
.WithMany(x => x.Cities)
.HasForeignKey(x => x.CountryId);
并且不要忘记重新生成迁移。