所謂EF延遲加載,就是使用Lamabda或Linq查詢數據時,EF並不會將數據直接查詢出來,而是在用到的這個查詢結果的時候才會加載到內存中。延遲加載也可以理解成 按需加載,顧名思義,就是按照所需的數據,加載數據。那么為什么要使用延遲加載?使用延遲加載的優缺點是什么?下面通個幾個例子來說明。
首先用到了兩張非常簡單的表

T_Artcle 文章表,T_User用戶表,用UserID作為外鍵關聯,插入下面的數據
INSERT INTO T_User VALUES('nee32')
INSERT INTO T_Artcle VALUES('test title',1)
然后新建一個控制台應用程序,導入這兩張表,注意添加表的時候把確定所生成對象名稱的單復數形式勾上
一、EF中的查詢Where與集合List中的Where的區別
EF中的where

EF中的Where返回的是一個IQueryable,我們再寫一個list集合,看看返回的是什么

奇怪,都是Where方法,但是返回的結果卻完全不一樣,原因是因為 集合的查詢方法Where是來自System.Linq.Enumerable里給IEnumerable接口添加的擴展方法,而EF上下文中的DBSet<T>里的查詢方法Where來自System.Linq.Queryable里給IQueryable接口添加的擴展方法,雖然都是調用的Where方法,但是這兩個方法完全不一樣。因為IQueryable這個接口,所以就支持延遲查詢。
二、即時查詢與延遲查詢
1、即時查詢
首先在執行查詢的時候打一個斷點

再用 sql server profiler監聽 執行的sql

可以看到,執行完斷點就馬上查詢了數據庫,所以上面的查詢是即時的
2、延遲查詢
我們改一下上面的代碼

設置斷點再用 sql server profiler監聽,發現斷點之前並沒有執行任何sql

只有在用到使用它的時候 T_User user = query.FirstOrDefault()

延遲查詢的優點:例如有一個博客查詢頁面,上面有發布時間、關鍵字、分類等查詢條件,當查詢條件個數不確定的時候,where並沒有立即去查詢數據庫,而是把所有的條件都確定好之后,才根據這些where條件生成一條相應的sql去查詢數據庫。
3、外鍵實體的延遲加載
本質:對與外鍵屬性,EF會在用到這個外間屬性的時候才去查詢相應的表
先在EDM實體模型中看下用戶與文章的關系

生成的類代碼如下:
public partial class T_Artcle
{
public int Id { get; set; }
public string Title { get; set; }
public int UserID { get; set; }
public virtual T_User T_User { get; set; }
}
public partial class T_User
{
public T_User()
{
this.T_Artcle = new HashSet<T_Artcle>();
}
public int Id { get; set; }
public string UserName { get; set; }
public virtual ICollection<T_Artcle> T_Artcle { get; set; }
}
edmx 幫我們生成了相應的主外鍵關系
例如,查詢出 文章表 ID為1的 的文章用戶
static void Main(string[] args)
{
Nee32Entities db = new Nee32Entities();//創建一個上下文對象
var query = db.T_Artcle.Where(u => u.Id == 1);
T_Artcle artcle = query.FirstOrDefault();//只查詢了文章表
Console.WriteLine(artcle.T_User.UserName);//查詢了文章對應的用戶表
Console.ReadKey();
}
在Console.WriteLine(artcle.T_User.UserName);這一行設置斷點,使用 sql server profiler監聽一下

這里只是查詢了文章表,並沒有查詢用戶表,繼續逐步執行

這個時候EF去用用戶表了,因為這里用到了文章表的外鍵屬性,程序輸出 nee32
完
