首页 > 解决方案 > 为什么 EF Core 生成带有基于字符串的索引的 asp.net 标识表(在我将其更改为 int 之后)?

问题描述

基于这个问题的回答:Why asp.net Identity user id is string?

我在我的项目中进行了这些更改,当我创建迁移时,它首先创建具有基于字符串的索引的表,然后迁移尝试将其类型更改为 int,但它失败并告诉我删除列并添加再次使用新类型。当我这样做时,它给了我更多错误,因为其他身份表依赖于这些 id-s,所以我应该先删除外键然后删除列,添加新类型的列然后我应该重新创建外键。

在我看来,这需要付出很多努力。上面提到的问题没有提到这种问题。是否有任何简单的解决方案,或者我每次创建新项目并尝试更改身份以使用基于 int 的主键时都必须手动编写迁移?

标签: asp.net-coreentity-framework-coreasp.net-core-identity

解决方案


我认为与其尝试在迁移中进行尽可能少的更改,不如简单地删除所有外键和表并使用正确类型的 Id 重新创建它们。

这样我可以避免 EF 由于将字符串更改为 int 而引发的错误。

而不是在迁移中做这样的事情:

    migrationBuilder
       .AlterColumn<int>(
            name: "Id",
            table: "AspNetUsers",
            oldClrType: typeof(string));

我做这样的事情:

        migrationBuilder.DropForeignKey(name: "FK_AspNetRoleClaims_AspNetRoles_RoleId", table: "AspNetRoleClaims");
        // Drop the other FKs as well.

        migrationBuilder.DropTable(name: "AspNetRoles");
        // Drop the other tables as well.

        migrationBuilder.CreateTable(
            name: "AspNetUsers",
            columns: table => new
            {
                Id = table.Column<int>(nullable: false),
                UserName = table.Column<string>(maxLength: 256, nullable: true),
                NormalizedUserName = table.Column<string>(maxLength: 256, nullable: true),
                Email = table.Column<string>(maxLength: 256, nullable: true),
                NormalizedEmail = table.Column<string>(maxLength: 256, nullable: true),
                EmailConfirmed = table.Column<bool>(nullable: false),
                PasswordHash = table.Column<string>(nullable: true),
                SecurityStamp = table.Column<string>(nullable: true),
                ConcurrencyStamp = table.Column<string>(nullable: true),
                PhoneNumber = table.Column<string>(nullable: true),
                PhoneNumberConfirmed = table.Column<bool>(nullable: false),
                TwoFactorEnabled = table.Column<bool>(nullable: false),
                LockoutEnd = table.Column<DateTimeOffset>(nullable: true),
                LockoutEnabled = table.Column<bool>(nullable: false),
                AccessFailedCount = table.Column<int>(nullable: false)
            },
            constraints: table =>
            {
                table.PrimaryKey("PK_AspNetUsers", x => x.Id);
            });

        // Create the other tables as well.

虽然我不确定是否有更优雅的方法将 AspNetUser 的每个 UserId、RoleId 和 Id、AspNetRole 表替换为 int。


推荐阅读