Asp.net

如何在 EF Core 中向身份使用者添加外鍵?

  • March 13, 2017

假設我在 EF 生成的數據庫中有一個Todo帶有相應Todo表 ( ) 的模型。DbSet<Todo>該表將每行儲存一個待辦事項。每個使用者(在 ASP.NET Core Identity + IdentityServer 應用程序中)將與多個待辦事項相關聯(一對多,一個使用者可以擁有多個待辦事項)。

我這樣做的方法是向模型添加一個UserId外鍵Todo,代表擁有 todo item 的使用者。

在使用 ASP.NET Core Identity 證明的類的同時,我將如何使用 EF Core 做到這一點?我的直覺是將以下內容添加到Todo類模型中:

public string UserId { get; set; }
[ForeignKey("UserId")]
public ApplicationUser User { get; set; }

這使用ApplicationUser(ASP.NET Core Identity 預設使用者類模型)作為發現來填充UserId外鍵。

這就是問題所在:當我執行時Update-Database出現錯誤!它說The entity type 'IdentityUserLogin<string>' requires a primary key to be defined.

瀏覽 的程式碼IdentityUserLogin,我可以看到它有一個UserId應該被視為主鍵的屬性,對吧?

無論如何,為了確保它註冊為主鍵,我將此程式碼添加到ApplicationUser’s OnModelCreatingmethod: builder.Entity<ApplicationUser>().HasKey(u => u.Id);。我仍然得到同樣的錯誤!不知道我在這裡做錯了什麼:(。編輯:是的,我呼叫了基類,所以這不是問題。

注意:我知道我可以為每個使用者添加一個包含待辦事項 ID 集合而不是外鍵的欄位,但我不確定這是否是這樣做的好方法。對此問題的指導表示讚賞。

您還沒有為此共享程式碼,但我猜您已經OnModelCreating在您的數據庫上下文中進行了覆蓋,但沒有呼叫base.OnModelCreating(modelBuilder);.

如果沒有基本呼叫,您的上下文不會應用與身份相關的架構。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
   // Add Identity related model configuration
   base.OnModelCreating(modelBuilder);

   // Your fluent modeling here
}

編輯:感覺想試一試,所以我只執行了以下任務。TLDR 將是它為我工作。我相信您遇到的問題與您正在製作的密鑰無關,並且一些不相關的東西導致了您的失敗,因為您遇到的失敗與您正在為其建構架構的表完全不同。

我使用 Identity 創建了一個新的 .net 核心 Web 應用程序。我做的第一件事是呼叫 update-database 從項目附帶的初始遷移中建構數據庫。這行得通。

接下來我添加了一個 Todo 類。沒有屬性,只有一個 Id 和 User 欄位。甚至沒有標記外鍵。

public class Todo
{
   public int Id { get; set; }
   public string UserId { get; set; }
   public ApplicationUser User { get; set; }
}

我將它作為 DbSet 添加到 ApplicationDbContext 中。對上下文的唯一更改是添加 ToDo DbSet

然後我呼叫add-migration todo包管理器控制台來建構 todo 遷移。在 FK 到位的情況下,它按預期生成。

public partial class Todo : Migration
{
   protected override void Up(MigrationBuilder migrationBuilder)
   {
       migrationBuilder.CreateTable(
           name: "Todos",
           columns: table => new
           {
               Id = table.Column<int>(nullable: false)
                   .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
               UserId = table.Column<string>(nullable: true)
           },
           constraints: table =>
           {
               table.PrimaryKey("PK_Todos", x => x.Id);
               table.ForeignKey(
                   name: "FK_Todos_AspNetUsers_UserId",
                   column: x => x.UserId,
                   principalTable: "AspNetUsers",
                   principalColumn: "Id",
                   onDelete: ReferentialAction.Restrict);
           });

       migrationBuilder.CreateIndex(
           name: "IX_Todos_UserId",
           table: "Todos",
           column: "UserId");
   }

   protected override void Down(MigrationBuilder migrationBuilder)
   {
       migrationBuilder.DropTable(
           name: "Todos");
   }
}

然後,我在 About 控制器操作中添加了一些程式碼,以將記錄粘貼到表中以確保 FK 正常工作。它是。

public async Task<IActionResult> About()
{
   var user = await _userManager.GetUserAsync(HttpContext.User);
   var todo = new Todo
   {
       User = user
   };
   _context.Todos.Add(todo);
   await _context.SaveChangesAsync();

   return View();
}

數據庫中記錄的螢幕截圖以及表和鍵: 在此處輸入圖像描述

除了在 Todo 類中有更多欄位這一顯而易見的問題之外,是否有一些完全不同的東西,你做了不同的事情,可能會導致我們遇到問題?

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