2017-08-18 83 views
1

我是新的實體框架代碼優先。這是我在ASP.NET MVC中的學習,使用代碼優先進行數據庫創建。如何使用ASP.NET MVC中的實體框架將記錄插入到具有外鍵的表中

我有兩個類:

public class Student 
{ 
    public int StudentId { get; set; } 
    public string Name { get; set; } 
    public int Standard { get; set; }    
    public int SubjectId { get; set; }  

    [ForeignKey("SubjectId")] 
    public ICollection<Subject> Subjects { get; set; } 
} 

public class Subject 
{ 
    [Key] 
    public int SubjectId{ get; set; } 
    public string SubjectName { get; set; } 
} 

我試圖插入Student記錄到Student表,其中有一個外鍵SubjectId引用Subject表。

我想它有兩種可能的方式:

第一種方法

using(var cxt = new SchoolContext()) 
{ 
    Subject sub = new Subject() { SubjectId = 202, SubjectName ="Geology" }; 
    Student stu = new Student() { Name = "Riya", SubjectId = 202 }; 
    cxt.Subjects.Add(sub); 
    cxt.Students.Add(stu);   

    cxt.SaveChanges(); 
} 

在這裏,我創建了一個新Subject實例,其中有SubjectId=202。現在,當我創建Student對象並將值202分配給SubjectId時,會有一個Insert語句衝突。雖然有SubjectSubjectId = 202,那麼爲什麼會出現插入衝突?而當我調試時,我看到導航屬性Subjects在這裏爲空。我不明白這一點。

第二種方法:

using(var cxt=new SchoolContext()) 
{ 
    Student stu = new Student() { Name = "Riya" }; 
    Subject sub = new Subject() { SubjectId = 202, SubjectName = "Geology" }; 
    stu.Subjects.Add(sub); 
    cxt.Students.Add(stu);    

    cxt.SaveChanges(); 
} 

,但我得到了一個空引用異常

對象引用未設置到對象

的情況下爲什麼空嗎?

所以在這裏我的問題是:

  1. 是什麼在StudentSubjectId是什麼意思?即它的價值是什麼?我們可以明確地設置它,如果是的話,它會引用Subject表的主鍵嗎?如果不是,是否僅爲EF代碼慣例指定?

  2. 同樣:導航屬性的作用是什麼?爲什麼它是空的,什麼時候它不會爲空?

我的導航屬性的基本理解是,它是用來做EF確定這兩個實體之間的關係。

任何人都可以請澄清一些例子,將不勝感激。

+1

學生課中不應該有SubjectId。您可能正在尋找[多對多]:一個學生可以擁有一個或多個教師很多科目,一個科目可以有很多學生。 –

+0

在'Student'中,請務必將您的'Subjects'集合標記爲虛擬。 – Tipx

+0

@Tipx - 虛擬僅在需要[延遲加載](https://stackoverflow.com/questions/15247614/understanding-code-first-virtual-properties)時才需要。這不是問題。 –

回答

1

你基本上都在創建一個Student和一個新的Subject,在你的方法。但根據我的理解,你真正想要做的是創建一個新的Student,並將現有的Subject(與SubjectId = 202)分配給它 - 對嗎?

SubjectIdStudent類可以在此設置絕對沒有任何意義 - 因爲你有一個1:N StudentSubject之間的關係。你需要使用ICollection<Subject>處理0:N科這個學生就讀

對於 - 使用此代碼:

using(var ctx = new SchoolContext()) 
{ 
    // create the *NEW* Student 
    Student stu = new Student() { Name = "Riya" }; 

    // get existing subject with Id=202 
    Subject sub = ctx.Subjects.FirstOrDefault(s => s.SubjectId == 202); 

    // Add this existing subject to the new student's "Subjects" collection 
    stu.Subjects.Add(sub); 

    // Add the new student to the context, and save it all. 
    ctx.Students.Add(stu);   

    ctx.SaveChanges(); 
} 

那會做 - 一個新的學生將被插入到你的數據庫表和學生和他的學科之間的1:n關係將建立。

+0

我不能這樣做,創建一個新的'Subject',調用'SaveChanges',然後創建'Student' retreive Subject並將這個'subject'添加到新的'Student'中 –

相關問題