实体框架核心"实体类型' XXX'需要定义主键。"

时间:2017-06-21 02:46:43

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

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

2 个答案:

答案 0 :(得分:12)

您无法单独使用数据注释定义compoiste键。您需要使用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

答案 1 :(得分:1)

您的LectureCompletion类需要正确定义主键。[Key]是主键注释,用于明确告诉EntityFramework将其设置为主键,否则约定将接管。

即,名为ID或以ID为后缀的属性,例如PokemonID表的Pokemon。在这种情况下,IDId不区分大小写。

仅当您希望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目前似乎没有任何效果。