【问题标题】:Entity Framework Core "The entity type 'XXX' requires a primary key to be defined."Entity Framework Core “实体类型‘XXX’需要定义一个主键。”
【发布时间】:2017-11-23 18:20:22
【问题描述】:

因此,我目前正在尝试使用 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; }
}

我想使用UserId 和LectureId 作为唯一的复合键。但是我收到此错误:

实体类型“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);
    }
}

【问题讨论】:

    标签: c# sql entity-framework asp.net-core asp.net-identity


    【解决方案1】:

    您不能单独使用数据注释来定义复合键。您需要改用 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

    【讨论】:

    • 太棒了!谢谢!阅读您提供的链接,这很有效并学到了一些东西。只是想补充一点,外键 UserId 需要是字符串而不是 int。
    • 即使采用这种结构,在加载child的children(二级)时也会出现错误
    【解决方案2】:

    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 目前似乎没有任何效果。

    【讨论】:

      猜你喜欢
      • 2020-10-18
      • 1970-01-01
      • 1970-01-01
      • 2021-01-25
      • 1970-01-01
      • 2021-05-11
      • 1970-01-01
      • 1970-01-01
      • 2021-07-23
      相关资源
      最近更新 更多