2011-06-07 85 views
2

我發現使用Linq-to-SQL創建新對象時,只有在調用SubmitChanges之後才能訪問外鍵成員新對象「正在創建」的上下文。當然,我明白,在將新對象提交給數據庫之前,FK並不存在 - 但似乎有信息允許查找工作。以下面的代碼爲例。Linq-to-SQL:在提交事務之前無法訪問外鍵

public Course Create(string name, int teacherID) 
{ 
    using (MyDataContext context = new MyDataContext()) 
    { 
     Course c = new Course(); 

     c.Name = name; 
     c.TeacherID = teacherID; //FK here, assume the value references a valid Teacher. 
     context.Courses.InsertOnSubmit(c); //c now has a context it can use. 

     //Try to do some validation here, before commiting the Course to the database. 
     //c.Teacher will be null here, leading to an exception. 
     if (c.Teacher.FirstName.Equals("Phil")) 
      throw new ApplicationException("Phil quit last year."); //Throwing here would cause the transaction to never commit, good. 

     context.SubmitChanges(); 

     //Email the teacher. 
     SendEmail(c.Teacher.EmailAddress); //c.Teacher is no longer null, this would work fine. 
    } 
} 

上面的代碼有一些評論,應該說明我在問什麼。我的問題基本上是這樣的:

爲什麼我必須先爲SubmitChanges查找基於已經設置在對象上的原始ID(FK)的值?

回答

4

是的,c.Teacher在那裏爲空。 Linq-To-Sql沒有提供任何機制來加載基於手動填充的外鍵列的實體(至少,直到你到達SubmitChanges)。當然,如果你已經從數據庫中提取實體,它會延遲加載 - 但是在這裏你正在創建它。無論是通過在teacher實體(而不是ID)或手動獲取的實體,並設置改爲:

c.Teacher = teacher 

代替

c.TeacherID = teacherID 
+0

傳遞的實體就會變得混亂,如果它從同一個DataContext的不我希望不必每個** FK實體都預取**。但是,唉,我可能必須這樣做。謝謝。 – 2011-06-07 23:14:12

+0

如果您確實需要從中獲取數據,則只需預先獲取它們即可。 (顯然,在這種情況下,你是否可以問)爲什麼在調用另一個方法時涉及單獨的datacontext?通常的模型是每個線程/請求/等的一個數據上下文。否則,您可以傳入實體,但*仍*設置「EntityID」。只要確保你引用傳入的參數,而不是實體屬性。 – 2011-06-07 23:17:26

+0

問題的真正原因在於,如果您爲每個根據傳入參數設置屬性的實體都有一個create方法,然後在*之前調用一些'Validate(theObject)'方法對其屬性**進行驗證, *將其提交給數據庫。這就是爲什麼我說「預取每個FK」,因爲你不知道「Validate」方法需要檢查哪些。 – 2011-06-07 23:26:49