Search code examples
c#entity-frameworkcode-first

FK constraint at SaveChange()


Learning EF6 code-first. By foreign key convention, I would have StandardId as Student Table's FK instead of the ugly Standards_StandardId. Even though I follow the tutorial word-to-word, I got exception while updating the database at ctx.SaveChanges().

I thought some convention of my Entity Framework is not working properly. So I tried DataAnnotation [ForeignKey("StandardId")] on public Standard Part { get; set; } to override the FK. But still I receive the exact same error!

Is my SQL Server "not talking with" my Entity Framework, or something is corrupted? Below are all the codes and error messages in detail:

Entity Model

public class Student {
    public Student() { }
    public int StudentID { get; set; }
    public string StudentName { get; set; }

    //Foreign key for Standard
    public int StandardId { get; set; } <- StandardId, not Standard_StandardId
    public Standard Standard { get; set; } }

public class Standard {
    public Standard() { }
    public int StandardId { get; set; }
    public string StandardName { get; set; } 
    public ICollection<Student> Students { get; set; } }

DbContext and DbSet

namespace EF_Code_First_Tutorials {
    public class SchoolContext: DbContext {
        public SchoolContext(): base() { }
        public DbSet<Student> Students { get; set; }
        public DbSet<Standard> Standards { get; set; } } }

Main

class Program {
    static void Main(string[] args) {
        using (var ctx = new SchoolContext()) {
            Student stud = new Student() { StudentName = "New Student" };  
            ctx.Students.Add(stud);
            ctx.SaveChanges(); } } } <-- ERROR!

In Visual Studio

An exception of type 'System.Data.Entity.Infrastructure.DbUpdateException' occurred in EntityFramework.dll but was not handled in user code

In InnerException

{"The INSERT statement conflicted with the FOREIGN KEY constraint \"FK_dbo.Students_dbo.Standards_StandardId\". The conflict occurred in database \"EF_Code_First_Tutorials.SchoolContext\", table \"dbo.Standards\", column 'StandardId'.\r\nThe statement has been terminated."}


Solution

  • Your relationship between Student and Standard is not optional, it is required. It means, that when you save a Student, it has to have StandardId assigned to an existing Standard record's id.

    EDIT:

    So, your program should include creation of the Standard object:

    class Program {
        static void Main(string[] args) {
            using (var ctx = new SchoolContext()) {
                Student stud = new Student() { StudentName = "New Student" };  
                ctx.Students.Add(stud);
                Standard stan = new Standard { StandardId = 524 };
                stud.StantardId = stan.StandardId;
                ctx.Standards.Add(stan);
                ctx.SaveChanges(); } } }
    

    If you want to make the relationship optional, the Student should have

    public int? StandardId { get; set; }

    Instead of:

    public int StandardId { get; set; }