Home > Enterprise >  The entity type 'List<int>' requires a primary key to be defined. But it is defined
The entity type 'List<int>' requires a primary key to be defined. But it is defined

Time:12-03

I'm new to the Entity Framework and I'm having problems with properly defining relationships.

I have a Student class, and a Course class and it's supposed to me a many to many relationship. A student can do one or more courses and a course can be done by one or more students. But when I try to run the command dotnet ef migrations add InitialCreate to create the initial migration, I get the error: The entity type 'List<int>' requires a primary key to be defined. Here is the Student class

using System;
using System.ComponentModel.DataAnnotations;
using Microsoft.EntityFrameworkCore;

namespace Advisment.Models
{
public class Student
{
    public int Id { get; set; }
    public string Name { get; set; }

    public int MajorId { get; set; }

    public int AdvisorId { get; set; }

    public List <int> CompletedCourses { get; set; }//List of courses done by student

    public ICollection <Course> Courses { get; set; }//Reference the Course class

    public Advisor Advisor { get; set; }

    public Major Major { get; set; }
    
}
}

And here is the the Course class:

using System;
using System.ComponentModel.DataAnnotations;

namespace Advisment.Models
{
public class Course
{
    [Key]
    public int CourseId { get; set; }
    public string CourseName { get; set; }

    public int MajorId { get; set; }
    
    public ICollection <Student> Students { get; set; }//Store student objects

    public Major Major { get; set; }
}
}

From my understanding the ICollection(s) is used to reference the classes, but I'm not sure if I'm using it correctly.

CodePudding user response:

Hello In order to create relationships between tables you will need to add a

Foreign Key which is the primary key in the table you try to connect.

So you need to the table/class that you want to the Foreign Key from

which you did in the Course List and implemented the many to many

relationships.

so now all you have to do is to add the foreign key to students class

for example :

public int CourseId { get; set; }

Also add Primary Key [Key] to your student

CodePudding user response:

You should Add a third class which should be a bridge between student and courses. Because relationship between Student and Courses are many to many.

Consider this class :

public class Enrollment
{
    public int CourseId { get; set; }
    public int StudentId { get; set; }
    public Student Student { get; set; }
    public Course { get; set; }
    public char Grade {get; set; }
}

Change your student class to be like this

public class Student
{
    public int Id { get; set; }
    public string Name { get; set; }

    public int MajorId { get; set; }

    public int AdvisorId { get; set; }

    public ICollection <Enrollment> Enrollments { get; set; }//Reference the Enrollment class

    public Advisor Advisor { get; set; }

    public Major Major { get; set; }
    
}

and Course class to be like this :

public class Course
{
    [Key]
    public int CourseId { get; set; }
    public string CourseName { get; set; }

    public int MajorId { get; set; }
    
    public ICollection <Enrollment> Enrollments{ get; set; }//Store student objects

    public Major Major { get; set; }
}

In Fluent Api, you need to setup the relationship of the bridge Enrollments table like this :

   modelBuilder.Entity<Enrollment>()
        .HasKey(c => new { c.CourseId, c.StudentId});

    modelBuilder.Entity<Enrollment>()
                .HasOne(c => c.Student)
                .WithMany(s => s.Enrollments)
                .HasForeignKey(h => h.StudentId)
                .IsRequired();

            modelBuilder.Entity<Enrollment>()
                .HasOne(c => c.Course)
                .WithMany(j => j.Courses)
                .HasForeignKey(h => h.CourseId)
                .IsRequired();

To retrieve all the courses that the student take, you can use this method

context.Students.Include(s => s.Enrollments).ThenInclude(e => e.Course).ToList();
  • Related