4

私は、Todoモデルに対応するテーブル(DbSet<Todo>)をEF生成データベースに持っています。テーブルには、行ごとにToDo項目が格納されます。各ユーザ(ASP.NET Core Identity + IdentityServerアプリ内)は、複数のToDo項目(1対多、複数のToDo項目を持つことができます)に関連付けられます。EFコアのIDユーザーに外部キーを追加するにはどうすればよいですか?

todoアイテムを所有するユーザーを表すTodoモデルにUserId外部キーを追加する方法です。

ASP.NETコアアイデンティティによって証明されたクラスを利用しながら、EFコアでどのようにしたらよいですか?私の直感はTodoクラスモデルに以下を追加しました:

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

これは、外部キーでUserIdを移入する発見として(ASP.NETコアアイデンティティデフォルトのユーザークラスモデル)ApplicationUserを使用しています。

ここに問題があります:Update-Databaseを実行するとエラーが発生します。それはThe entity type 'IdentityUserLogin<string>' requires a primary key to be defined.と言います。

IdentityUserLoginのコードを参照すると、プライマリキーと見なされるプロパティUserIdがあります。

とにかく、プライマリキーとして登録されていることを確認するために、このコードをApplicationUserOnModelCreatingメソッドに追加しました:builder.Entity<ApplicationUser>().HasKey(u => u.Id);。私はまだ同じエラーが発生します!

注:ToDoアイテムのコレクションを運ぶ各ユーザーにフィールドを追加できることは分かっていますが、私はここで間違っていますか分かりません:(編集:はい、それは問題ではないので基本クラスを呼び出しました。外部キーを持っているのではなく、IDを持っていますが、これが良い方法かどうかは分かりません。この問題のガイダンスは高く評価されています。

答えて

6

あなたはこのコードを共有していませんが、あなたのデシベルコンテキストでOnModelCreatingのオーバーライドをしたが、base.OnModelCreating(modelBuilder);と呼ばれていない。

ベースコールがなければ、あなたのコンテキストはアイデンティティ関連のスキーマを適用していない。

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

    // Your fluent modeling here 
} 

編集:この渦を与えるように感じたので、私はちょうど、以下のタスクを実行しました。 TLDRはそれが私のために働いたことでしょう。あなたが持っている問題は、作成しているキーとは無関係で、無関係なものはあなたの失敗を引き起こすと考えています。あなたが得ている失敗は、スキーマを構築しようとしているものとはまったく別のテーブルです。

アイデンティティを使用して新しい.netコアWebアプリケーションを作成しました。私が最初にしたことは、プロジェクトが付属していた最初の移行からDBを構築するために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"); 
    } 
} 

私は、ちょうど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(); 
} 

テーブルとキーと一緒にDBのレコードのスクリーンショット: あなたの藤堂クラスの複数のフィールドを持っていることは明らか以外enter image description here

はあなたが異なってやったことを大幅に異なるものがありますそれは私たちの問題につながるかもしれませんか?

+0

いいえ、それはまさに私がやったことです。実際、ASP.NET Core Identityによって生成されたコードにはオーバーライドされていましたので、Fluent APIを 'base.OnModelCreating(modelBuilder);'の行の下に追加しました。まだそれらのエラーを取得しています! @Biarity hrm。 – Biarity

+0

AspNetUserLoginsは、AspNetUsersとは異なるテーブルで、キーが効果がなかったのはこのためです。テーブルの通常のビルドの方法に何かが入っているはずです。 –

+0

Fluent APIを使用しなくても機能しませんか?外部キー・タグの検出としてApplicationUserの主キーを使用すると、それがなぜちょうど推論できないのですか?たぶん私は何かが欠けている(つまり、とにかくEFでこれをやり遂げる正しい方法ですか?) – Biarity

3

デイブ、あなたのソリューションは正常に機能しました!それは(パッケージマネージャコンソールに)必要なとき

public DbSet<MyClass> MyClass { get; set; } 

と:: PM>をDbSetがファイルApplicationDbContext.csにのようなものを追加する手段としてApplicationDbContextにクラスを追加する

読者のためだけでいくつかの詳細、追加マイグレーションMyClass PM>更新データベース

関連する問題