c# - .NET Core 2.2 Migration Builder 无法删除索引
问题描述
我正在尝试从 IdentityUserRole 表中名为 UserRole 的列中删除索引/外键。
UserRole 有 2 列。用户 ID 和角色 ID。两者都是主键。
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
var rolesTable = modelBuilder.Entity<Role>().ToTable("Role");
var userRolesTable = modelBuilder.Entity<UserRole>().ToTable("UserRole");
var userClaimsTable = modelBuilder.Entity<IdentityUserClaim<string>>().ToTable("UserClaim");
var usersTable = modelBuilder.Entity<User>().ToTable("User");
modelBuilder.Entity<Role>(builder =>
{
builder.Metadata.RemoveIndex(new[] { builder.Property(u => u.NormalizedName).Metadata });
});
modelBuilder.Entity<UserRole>(builder =>
{
builder.Metadata.RemoveIndex(new[] { builder.Property(u => u.RoleId).Metadata});
});
}
但是,每当我运行迁移并更新数据库时,仍会出现此索引:
IX_UserRole_RoleId 列 RoleId
编辑:这是生成的迁移
migrationBuilder.CreateTable(
name: "UserRole",
columns: table => new
{
UserId = table.Column<string>(nullable: false),
RoleId = table.Column<string>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_UserRole", x => new { x.UserId, x.RoleId });
table.ForeignKey(
name: "FK_UserRole_Role_RoleId",
column: x => x.RoleId,
principalTable: "Role",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_UserRole_User_UserId",
column: x => x.UserId,
principalTable: "User",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_UserRole_RoleId",
table: "UserRole",
column: "RoleId");
解决方案
按照惯例,EF Core 为每个 FK 列添加索引,该列不是另一个索引的前导部分。即使您没有使用这些索引的查询,但通常它们对于强制执行 FK 约束以及实现级联删除很有用,因此事实上它们是关系数据库设计中的标准(类似于用于强制唯一索引的唯一索引/ PK约束等)但这不是这里的问题。
RemoveIndex
您可能认为它是缺陷,但即使您使用显式元数据 API ,也无法删除约定引入的索引。它会删除它们,但随后它们会自动添加回来。
这是因为 EF Core 约定不是静态应用的。它们由监听不同模型元数据更改的类实现,这些更改触发“重新应用”约定。
很快,您将无法使用元数据/流式 API 删除此类索引。如果您真的想删除它们(我不推荐),您应该手动编辑生成的迁移并从Up
和Down
方法中删除相应的创建/删除命令。
推荐阅读
- django - Django:重复键值违反了 Postgresql 而不是 SQlite 的唯一约束 -> 为什么?
- flutter - 无效值:只有有效值是 0:1 - Flutter
- python - 如何使用 Pymongo 使用默认语言创建文本索引
- docker - 为在 docker 上运行的 invoice-ninja 实例设置用户和组
- java - 原子地运行两个操作
- python - 网站上挂着漂亮的汤网刮痧
- python - 测量海龟之间的距离
- linux - 在 FTP 期间在 Linux 服务器上的 shell 脚本中获取远程位置的文件计数
- reactjs - 将主屏幕拆分为组件后出现 navigation.navigate 类型错误
- java - 尝试生成 Jasper 报告时出现异常