Asp.net

實體框架 - 對象 ‘PK_AspNetUserTokens’ 依賴於列 ‘UserId’

  • October 8, 2020

我在 VS 2017(版本 15.5)中創建了一個新的 ASP.NET Core 2 MVC 項目,將使用者 ID 類型從字元串更改為 Guid(還將 ApplicationUser 類名更改為使用者),添加了我的模型,然後

Add-Migration Init
Update-Database

但它會產生錯誤並且不會創建數據庫。

The object 'PK_AspNetUserTokens' is dependent on column 'UserId'.
ALTER TABLE ALTER COLUMN UserId failed because one or more objects access this column.

這是我的背景:

public class ApplicationDbContext : IdentityDbContext<User, IdentityRole<Guid>, Guid>
{
   public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
       : base(options)
   {
   }

   public DbSet<TvShow> TvShows { get; set; }
   public DbSet<Episode> Episodes { get; set; }
   public DbSet<Subscription> Subscriptions { get; set; }
   public DbSet<Notification> Notifications { get; set; }
   public DbSet<Genre> Genres { get; set; }
   public DbSet<TvShowGenre> TvShowGenre { get; set; }

   protected override void OnModelCreating(ModelBuilder builder)
   {
       base.OnModelCreating(builder);

       builder.Entity<Subscription>()
           .HasKey(c => new { c.TvShowId, c.UserId });

       builder.Entity<TvShowGenre>()
           .HasKey(c => new { c.TvShowId, c.GenreId });
   }
}

這是我的遷移類(僅 up 方法):

public partial class Init : Migration
{
   protected override void Up(MigrationBuilder migrationBuilder)
   {
       migrationBuilder.DropIndex(
           name: "UserNameIndex",
           table: "AspNetUsers");

       migrationBuilder.DropIndex(
           name: "IX_AspNetUserRoles_UserId",
           table: "AspNetUserRoles");

       migrationBuilder.DropIndex(
           name: "RoleNameIndex",
           table: "AspNetRoles");

       migrationBuilder.AlterColumn<Guid>(
           name: "UserId",
           table: "AspNetUserTokens",
           nullable: false,
           oldClrType: typeof(string));

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

       migrationBuilder.AlterColumn<Guid>(
           name: "RoleId",
           table: "AspNetUserRoles",
           nullable: false,
           oldClrType: typeof(string));

       migrationBuilder.AlterColumn<Guid>(
           name: "UserId",
           table: "AspNetUserRoles",
           nullable: false,
           oldClrType: typeof(string));

       migrationBuilder.AlterColumn<Guid>(
           name: "UserId",
           table: "AspNetUserLogins",
           nullable: false,
           oldClrType: typeof(string));

       migrationBuilder.AlterColumn<Guid>(
           name: "UserId",
           table: "AspNetUserClaims",
           nullable: false,
           oldClrType: typeof(string));

       migrationBuilder.AlterColumn<Guid>(
           name: "Id",
           table: "AspNetRoles",
           nullable: false,
           oldClrType: typeof(string));

       migrationBuilder.AlterColumn<Guid>(
           name: "RoleId",
           table: "AspNetRoleClaims",
           nullable: false,
           oldClrType: typeof(string));

       migrationBuilder.CreateTable(
           name: "Genres",
           columns: table => new
           {
               Id = table.Column<long>(nullable: false)
                   .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
               Genres = table.Column<int>(nullable: false),
               IsFirst = table.Column<bool>(nullable: false)
           },
           constraints: table =>
           {
               table.PrimaryKey("PK_Genres", x => x.Id);
           });

       migrationBuilder.CreateTable(
           name: "Notifications",
           columns: table => new
           {
               Id = table.Column<long>(nullable: false)
                   .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
               CreateDate = table.Column<DateTime>(nullable: false),
               Message = table.Column<string>(nullable: true),
               Seen = table.Column<bool>(nullable: false),
               UserId = table.Column<Guid>(nullable: false)
           },
           constraints: table =>
           {
               table.PrimaryKey("PK_Notifications", x => x.Id);
               table.ForeignKey(
                   name: "FK_Notifications_AspNetUsers_UserId",
                   column: x => x.UserId,
                   principalTable: "AspNetUsers",
                   principalColumn: "Id",
                   onDelete: ReferentialAction.Cascade);
           });

       migrationBuilder.CreateTable(
           name: "TvShows",
           columns: table => new
           {
               Id = table.Column<long>(nullable: false)
                   .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
               ProductionYear = table.Column<string>(nullable: true),
               Status = table.Column<int>(nullable: false),
               Title = table.Column<string>(nullable: true)
           },
           constraints: table =>
           {
               table.PrimaryKey("PK_TvShows", x => x.Id);
           });

       migrationBuilder.CreateTable(
           name: "Episodes",
           columns: table => new
           {
               Id = table.Column<long>(nullable: false)
                   .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
               BroadcastDate = table.Column<DateTime>(nullable: true),
               Duration = table.Column<TimeSpan>(nullable: true),
               Number = table.Column<int>(nullable: true),
               Season = table.Column<string>(nullable: true),
               Title = table.Column<string>(nullable: true),
               TvShowId = table.Column<long>(nullable: false)
           },
           constraints: table =>
           {
               table.PrimaryKey("PK_Episodes", x => x.Id);
               table.ForeignKey(
                   name: "FK_Episodes_TvShows_TvShowId",
                   column: x => x.TvShowId,
                   principalTable: "TvShows",
                   principalColumn: "Id",
                   onDelete: ReferentialAction.Cascade);
           });

       migrationBuilder.CreateTable(
           name: "Subscriptions",
           columns: table => new
           {
               TvShowId = table.Column<long>(nullable: false),
               UserId = table.Column<Guid>(nullable: false)
           },
           constraints: table =>
           {
               table.PrimaryKey("PK_Subscriptions", x => new { x.TvShowId, x.UserId });
               table.ForeignKey(
                   name: "FK_Subscriptions_TvShows_TvShowId",
                   column: x => x.TvShowId,
                   principalTable: "TvShows",
                   principalColumn: "Id",
                   onDelete: ReferentialAction.Cascade);
               table.ForeignKey(
                   name: "FK_Subscriptions_AspNetUsers_UserId",
                   column: x => x.UserId,
                   principalTable: "AspNetUsers",
                   principalColumn: "Id",
                   onDelete: ReferentialAction.Cascade);
           });

       migrationBuilder.CreateTable(
           name: "TvShowGenre",
           columns: table => new
           {
               TvShowId = table.Column<long>(nullable: false),
               GenreId = table.Column<long>(nullable: false)
           },
           constraints: table =>
           {
               table.PrimaryKey("PK_TvShowGenre", x => new { x.TvShowId, x.GenreId });
               table.ForeignKey(
                   name: "FK_TvShowGenre_Genres_GenreId",
                   column: x => x.GenreId,
                   principalTable: "Genres",
                   principalColumn: "Id",
                   onDelete: ReferentialAction.Cascade);
               table.ForeignKey(
                   name: "FK_TvShowGenre_TvShows_TvShowId",
                   column: x => x.TvShowId,
                   principalTable: "TvShows",
                   principalColumn: "Id",
                   onDelete: ReferentialAction.Cascade);
           });

       migrationBuilder.CreateIndex(
           name: "UserNameIndex",
           table: "AspNetUsers",
           column: "NormalizedUserName",
           unique: true,
           filter: "[NormalizedUserName] IS NOT NULL");

       migrationBuilder.CreateIndex(
           name: "RoleNameIndex",
           table: "AspNetRoles",
           column: "NormalizedName",
           unique: true,
           filter: "[NormalizedName] IS NOT NULL");

       migrationBuilder.CreateIndex(
           name: "IX_Episodes_TvShowId",
           table: "Episodes",
           column: "TvShowId");

       migrationBuilder.CreateIndex(
           name: "IX_Notifications_UserId",
           table: "Notifications",
           column: "UserId");

       migrationBuilder.CreateIndex(
           name: "IX_Subscriptions_UserId",
           table: "Subscriptions",
           column: "UserId");

       migrationBuilder.CreateIndex(
           name: "IX_TvShowGenre_GenreId",
           table: "TvShowGenre",
           column: "GenreId");

       migrationBuilder.AddForeignKey(
           name: "FK_AspNetUserTokens_AspNetUsers_UserId",
           table: "AspNetUserTokens",
           column: "UserId",
           principalTable: "AspNetUsers",
           principalColumn: "Id",
           onDelete: ReferentialAction.Cascade);
   }
}

我遇到了和你一樣的問題。我刪除了我的文件夾“遷移”並再次添加遷移。由於之前遷移的變化,它無法相應地創建 FK。

在您的新遷移中,只需在更改列之前刪除鍵,然後再次添加相同的鍵。

protected override void Up(MigrationBuilder migrationBuilder)
{
   migrationBuilder.DropPrimaryKey("PK_AspNetUserTokens", "AspNetUserTokens");
   migrationBuilder.DropPrimaryKey("PK_AspNetUserLogins", "AspNetUserLogins");
       
   ...
   migrationBuilder.AlterColumn<string>(...);
   ...

   migrationBuilder.AddPrimaryKey("PK_AspNetUserTokens", "AspNetUserTokens", new string[] { "UserId", "LoginProvider", "Name" });
   migrationBuilder.AddPrimaryKey("PK_AspNetUserLogins", "AspNetUserLogins", new string[] { "LoginProvider", "ProviderKey" });
}

引用自:https://stackoverflow.com/questions/47718566