web-dev-qa-db-ja.com

Entity Framework Core「エンティティタイプ 'XXX'には、プライマリキーを定義する必要があります。」

そのため、現在、アプリケーションユーザーが完了した講義を表示するテーブル用に、Entity Framework Coreを使用したコードファーストマイグレーションを作成しようとしています。私のモデルは次のようになります。

public class LectureCompletion
{
    [Key,  Column(Order = 0)]
    [ForeignKey("Lecture")]
    public Lecture LectureId { get; set; }

    [Key,  Column(Order = 1)]
    [ForeignKey("User")]
    public ApplicationUser UserId{ get; set; }

    public bool Completed { get; set; }
}

UserIdLectureIdを一意の複合キーとして使用します。しかし、私はこのエラーを受け取ります:

エンティティタイプ「LectureCompletion」では、主キーを定義する必要があります。

正しい位置に重要な属性を明確に持っているので、なぜこれが起こっているのか分かりませんか? ApplicationUserを外部/主キーとして使用できますか?

これが私のLectureモデルです:

public class Lecture
{
    [Key]
    public int LectureId { get; set; }

    public string ModuleName { get; set; }
    public string LectureName { get; set; }
}

と私 ApplicationDBContext.cs

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public DbSet<Lecture> Lectures { get; set; }
    public DbSet<LectureCompletion> LectureCompletion { get; set; }

    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
        // Customize the ASP.NET Identity model and override the defaults if needed.
        // For example, you can rename the ASP.NET Identity table names and more.
        // Add your customizations after calling base.OnModelCreating(builder);
    }
}
11
Josh L

データ注釈のみで複合キーを定義することはできません。代わりにFluent APIを使用する必要があります。

public class LectureCompletion
{
    // which is your case.
    [ForeignKey(nameof(Lecture))] 
    public int LectureId { get;set; }
    public Lecture Lecture { get; set; }
    [ForeignKey(nameof(ApplicationUser))]
    public int UserId {get;set;}
    public ApplicationUser ApplicationUser { get; set; }
    public bool Completed { get; set; }
}


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

     // Define composite key.
     builder.Entity<LectureCompletion>()
         .HasKey(lc => new { lc.LectureId, lc.UserId });
}

https://docs.Microsoft.com/en-us/ef/core/modeling/keys

17
anserk

LectureCompletionクラスには、適切に定義される主キーが必要です。[Key]は、これを主キーとして設定するようにEntityFrameworkに明示的に指示する主キーアノテーションです。それ以外の場合は、慣習が引き継ぎます。

つまり、IDという名前のプロパティ、またはIDの接尾辞が付いたプロパティなどです。 PokemonIDテーブルの場合はPokemon。この場合、IDまたはIdは大文字と小文字を区別しません。

外部キー属性は、参照クラスとは異なる名前のLectureCompletionクラスの外部キープロパティ名が必要な場合にのみ使用されます。たとえば、ApplicationUserクラスの主キーがApplicationUserIdであるが、LectureCompletionクラスではUserIdにしたい場合は、属性を追加できます。

こうやって

public class LectureCompletion
{
    [Key] // Defined only once
    public LectureCompletionId { get;set; }

    // Not needed if Lecture class has the primary key property of LectureId,
    // which is your case.
    [ForeignKey("Lecture")] // Name of your navigation property below.
    public int LectureId { get;set; }

    public Lecture Lecture { get; set; }

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

    public ApplicationUser ApplicationUser { get; set; }

    public bool Completed { get; set; }
}

EntityFramework Coreについては、現在のところColumnOrderには何の効果もありません。

3
IvanJazz