Entity Framework Core “实体类型‘XXX’需要定义一个主键。”
Posted
技术标签:
【中文标题】Entity Framework Core “实体类型‘XXX’需要定义一个主键。”【英文标题】:Entity Framework Core "The entity type 'XXX' requires a primary key to be defined." 【发布时间】: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);
【问题讨论】:
【参考方案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 目前似乎没有任何效果。
【讨论】:
以上是关于Entity Framework Core “实体类型‘XXX’需要定义一个主键。”的主要内容,如果未能解决你的问题,请参考以下文章
Entity Framework Core中更改跟踪工作原理
Entity Framework Core中更改跟踪工作原理
如何将动态实体设置为 dbcontext Entity Framework Core?
什么是自有实体?何时以及为什么在 Entity Framework Core 中使用 Owned Entity?