2013-03-01 47 views
2

我是一位新的.NET開發人員。我有2個實體類,這樣實體框架查找結果vs LINQ結果

public class Student 
{ 
    public int userId { get; set; } 
    public string username { get; set; } 
    public string firstname { get; set; } 
    public string lastname { get; set; } 
    public string email { get; set; } 
    public Course course { get; set; } 
} 

public class Course 
{ 
    [Key] 
    public int courseId { get; set; } 
    public String courseName { get; set; } 
} 

我使用DB語境對象像這樣

using (MyDbContext db = new MyDbContext()) 

當我訪問使用

Student stdent = db.students.Find(1); 

原始類型的成員變量的Student對象(int,string)包含值,但課程變量類型(Course)返回null。

然而,當我使用

var result = from student in db.students where student.userId == 1 select student; 

結果包含值,所有成員變量(整個課程的對象是目前這裏)

這是預期的行爲還是我丟失或忽視的東西?

我甚至在我的數據庫上下文添加此構造函數來禁用延遲加載,但並沒有幫助

public MyDbContext() : base() 
    { 
     this.Configuration.LazyLoadingEnabled = false; 
    } 

回答

0

這裏發生的是,在第一種情況下(Find),您從數據庫中獲取對象。 Course不是延遲加載,所以Course參考是null

在第二種情況下,您只定義一個查詢但不執行它。我假設你循環播放結果,同時檢查Course是否存在。這會導致Course被加載,因爲您在執行時訪問Course導航屬性,它已成爲查詢的一部分。

如果你

var s = (from student in db.students where student.userId == 1 select student) 
     .Single(); 

你會發現,Course是空的,因爲學生是沒有在查詢ececuted時刻(在Single語句)的引用Course牽強。

+0

在第一種情況下,即使我將懶加載設置爲false(正如我在問題中所述)並嘗試訪問課程,它仍然會給我空值。任何想法爲什麼是這樣。 – user1429007 2013-03-01 15:25:49

+1

是的,它永遠不會延遲加載,因爲該屬性不是虛擬的。不考慮上下文的​​延遲加載設置。它僅由_eager loading_加載。也就是說,通過Include或通過在像Students.Select(s => s.Course)這樣的linq查詢中尋址,或通過Load方法。 – 2013-03-01 15:31:58

+1

我認爲你的一部分混亂是「lazy = false」(在上下文級別)的相反並不意味着「eager = true」。使用「lazy = true」時,如果可能的話發生延遲加載(即使用'virtual'屬性)。除非我上面提到的三個選項明確要求,否則「lazy = false」_no_加載將會發生。 – 2013-03-01 15:43:42

0

懶只加載初始對象被加載。爲了獲得第二個選項來檢索課程信息,您需要在加載選項中指定。

DataLoadOptions dataLoadOptions = new DataLoadOptions(); 
dataLoadOptions.LoadWith<Customer>(c => c.Course); 
db.LoadOptions = dataLoadOptions; 

Student stdent = db.students.Find(c=>c.userid == 1).FirstOrDefault(); 
+0

問題是關於實體框架。 – 2013-03-01 07:26:46