[英]Problem with migrations in column unique and auto-increment using MySQL
我在项目中使用 MySQL 数据库时遇到问题。 通常,某些项目表需要在输入数据时具有自动递增字段。 但是,在 MySQL 中,除了 Id 之外的列如果是唯一键,则只能自动递增。 例如:
public class Client
{
[Key]
public Guid Id { get; set; }
[MaxLength(200)]
public string Name { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Code { get; set; }
public DateTime BirthDate { get; set; }
}
但是,在 MySQL 中,除了Id
之外的列如果是唯一键,则只能自动递增。 例如:
modelBuilder.Entity<Client>()
.HasIndex(c => c.Code)
.IsUnique();
到现在为止还挺好。 Code
是正确的并且正在编译。 但是,在生成迁移时,结果是:
第1部分:
migrationBuilder.CreateTable(
name: "Client",
columns: table => new
{
Id = table.Column<Guid>(nullable: false),
Code = table.Column<int>(nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
Name = table.Column<string>(maxLength: 200, nullable: false),
BirthDate = table.Column<DateTime>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Client", x => x.Id);
}
);
第2部分:
migrationBuilder.CreateIndex(
name: "IX_Client_Code",
table: "Client",
column: "Code",
unique: true);
Ao executar a atualização do banco de dados( database update
)seguinte mensagem é exibida: Incorrect table definition; there can be only one auto column and it must be defined as a key
Incorrect table definition; there can be only one auto column and it must be defined as a key
。
此错误是由创建迁移的方式引起的。 在上面代码的第一部分中,“代码”已经明确表示为MySqlValueGenerationStrategy.IdentityColumn
,因此发生了错误。 为了解决这个问题,我必须创建两个迁移:第一个只将Code
字段添加到 single,第二个插入自动增量。 但是,我不想以这种方式使用它,因为每次我都必须至少创建两个迁移。
注意:在这种情况下,我可以放弃GUID
`` 并且只对表使用Code
( int
),但这是不可能的,因为我必须修改所有表的结构。 此外,我发现的另一个可能的解决方案是将 ID 和 Code 设为主键,但我不太可能以这种方式使用它。
有两种方法可以解决这个问题。
如果只想手动修复迁移代码,那么不要使用CreateIndex
,而只需将备用键添加到创建表操作的约束中:
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Client",
columns: table => new
{
Id = table.Column<Guid>(nullable: false),
Name = table.Column<string>(maxLength: 200, nullable: true),
Code = table.Column<long>(nullable: false)
.Annotation("MySql:ValueGenerationStrategy",
MySqlValueGenerationStrategy.IdentityColumn),
BirthDate = table.Column<DateTime>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Client", x => x.Id);
table.UniqueConstraint("AK_Client", x => x.Code); // <-- Add unique constraint
});
}
没有数据注释来定义备用键,但您可以使用fluent API :
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Client>(entity => entity.HasAlternateKey(e => e.Code));
}
这将创建与上述相同的工作迁移代码,并将产生以下CREATE TABLE
语句:
CREATE TABLE `Client` (
`Id` char(36) NOT NULL,
`Name` varchar(200) CHARACTER SET utf8mb4 NULL,
`Code` bigint NOT NULL AUTO_INCREMENT,
`BirthDate` datetime(6) NOT NULL,
CONSTRAINT `PK_Client` PRIMARY KEY (`Id`),
CONSTRAINT `AK_Client` UNIQUE (`Code`)
);
使用HasIndex().IsUnique()
将不起作用,因为这将生成一个CreateIndex()
调用,该调用与您在问题中描述的问题相同。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.