ASP.NET Mvc開發(fā)之EF延遲加載
先來看看定義
EF延遲加載:就是使用Lamabda表達(dá)式或者Linq 從 EF實(shí)體對(duì)象中查詢數(shù)據(jù)時(shí),EF并不是直接將數(shù)據(jù)查詢出來,而是在用到具體數(shù)據(jù)的時(shí)候才會(huì)加載到內(nèi)存。
一、實(shí)體對(duì)象的Where方法返回一個(gè)什么對(duì)象?
大家來看一下上一篇文章的代碼來分析一下:
#region 查詢文章列表+ActionResult Article()
/// <summary>
/// 查詢文章列表
/// </summary>
/// <returns></returns>
public ActionResult Article()
{
//通過db對(duì)象獲取文章列表
db.BlogArticles.Where(p => p.AIsDel == false);//使用Lamabda表達(dá)式來獲取為被刪除的文章
//使用Lamabda表達(dá)式來獲取數(shù)據(jù)
//返回一個(gè)List<T>的對(duì)象來存儲(chǔ)文章列表
List < Models.BlogArticle > list= db.BlogArticles.Where(p => p.AIsDel == false).ToList();
//也可以使用Linq來獲取數(shù)據(jù)
List<Models.BlogArticle> list1 = (from p in db.BlogArticles where p.AIsDel == false select p).ToList();
//使用ViewData來傳遞list對(duì)象
ViewData["DataList"] = list;
return View();
}
#endregion
為了體驗(yàn)延遲加載,我們把代碼做修改如下:
#region 查詢文章列表+ActionResult Article()
/// <summary>
/// 查詢文章列表
/// </summary>
/// <returns></returns>
public ActionResult Index()
{
//通過db對(duì)象獲取文章列表
db.BlogArticles.Where(p => p.AIsDel == false);//使用Lamabda表達(dá)式來獲取為被刪除的文章
DbQuery<Models.BlogArticle> query = (db.BlogArticles.Where(p => p.AIsDel == false)) as DbQuery<Models.BlogArticle>;
List<Models.BlogArticle> list = query.ToList();
//使用ViewData來傳遞list對(duì)象
ViewData["DataList"] = query;
return View();
}
#endregion
在這里我們?yōu)槭裁匆褂肈bQuery<T>來接收呢?
首先我們來看使用db.BlogArticles.Where()來獲取文章列表的時(shí)候,Where()方法給我們返回一個(gè)什么類型的對(duì)象呢?我們把鼠標(biāo)放在Where()方法上后,會(huì)發(fā)現(xiàn)Where會(huì)返回給我們一個(gè)IQueryable的泛型接口對(duì)象,如下圖:

那我們是不是需要使用IQueryable對(duì)象來接收獲取的對(duì)象呢,代碼如下:
//where()方法返回一個(gè)IQuery的接口 IQueryable < Models.BlogArticle > query= db.BlogArticles.Where(p => p.AIsDel == false);
這里的Query到底能不能取到值呢?我們來運(yùn)行調(diào)試程序,結(jié)果如下:

我們?cè)诰植孔兞看翱诳吹絈uery已經(jīng)取到了值。但是根據(jù)面向?qū)ο蟮脑瓌t,接口是不能直接實(shí)例化的,但是這里的代碼又是不報(bào)錯(cuò)的,那是為什么呢?
根據(jù)面向?qū)ο蟮睦锸咸鎿Q原則,我們都知道,這里實(shí)際上是返回了一個(gè)IQueryable對(duì)象的子類對(duì)象。
注意:C#里氏替換原則,子類對(duì)象可以賦值給父類對(duì)象。也就是說子類可以替換父類出現(xiàn)的地方。但是父類對(duì)象一定不可以替換子類對(duì)象。
也就是說Where()方法返回了一個(gè)IQueryable接口的子類對(duì)象,并且賦值給了它的父類對(duì)象IQueryable。
那么Where()到底返回了一個(gè)什么樣的對(duì)象呢(什么樣的IQueryable的子類對(duì)象呢)?
再次看上面的局變量窗口中query的返回值類型為,如下圖:

我們可以很明顯的看出,query的返回類型為DbQuery類型。
那我們就用DbQuery來接收對(duì)象,代碼如下:
因?yàn)閃here()方法返回的是IQueryable對(duì)象,所以要把對(duì)象轉(zhuǎn)換成DbQuery對(duì)象。
二、DbQuery<T>泛型接口類的延遲加載
上面的定義已經(jīng)說過了EF延遲加載的定義,那么在這里我們?cè)趒uery查詢到對(duì)象時(shí),數(shù)據(jù)庫有沒有執(zhí)行查詢操作呢?
這里我們借助SqlServer的自身的Profiler軟件來查看,
①打開SqlServerProfiler軟件,新建一個(gè)查詢,剛開始,是有查詢記錄的,如下圖:

②我們使用上圖中的,紅色箭頭指的橡皮,清除一下記錄,如下圖:

③我們?cè)俅螁?dòng)調(diào)試,運(yùn)行代碼,當(dāng)程序運(yùn)行到斷點(diǎn)的時(shí)候,我們看到query還沒有值,如下圖:

④單步調(diào)試,進(jìn)行下一步,我們?cè)诰植孔兞看翱谥邪l(fā)現(xiàn)query已經(jīng)取到了值,如下圖:

query的值,如下圖:

那么我們的SqlServerProfiler跟蹤器發(fā)生了什么變化呢?沒有發(fā)生任何變化,如下圖:

我們?nèi)绻褂肁DO.NET操作數(shù)據(jù)庫,查詢完數(shù)據(jù)后,數(shù)據(jù)會(huì)立即送給接收的對(duì)象(比如:DataTable對(duì)象),但是EF操作數(shù)據(jù)庫怎么卻沒有立即去查詢數(shù)據(jù)呢?
⑤DbQuery對(duì)象的延遲加載
當(dāng)我們使用query對(duì)象的時(shí)候才回去查詢數(shù)據(jù)庫,我們繼續(xù)執(zhí)行下一步,結(jié)果如下:

這個(gè)時(shí)候list取到了值,然后Sql Server Profiler也發(fā)生了變化,有了查詢數(shù)據(jù)庫的記錄,如下圖:

也就是說,當(dāng)query對(duì)象ToList()的時(shí)候,才發(fā)生了查詢數(shù)據(jù)庫的操作。
三、總結(jié)
1)EF中的DbQuery對(duì)象操作數(shù)據(jù)庫的時(shí)候發(fā)生延遲加載,而直接使用List<T>來接受對(duì)象時(shí)則不會(huì);
2)延遲加載不會(huì)立即去查詢數(shù)據(jù)庫,而是在使用數(shù)據(jù)的時(shí)候才EF才會(huì)去查詢數(shù)據(jù)庫。
以上就是關(guān)于ASP.NET Mvc開發(fā)過程中EF延遲加載的相關(guān)介紹,希望對(duì)大家的學(xué)習(xí)有所幫助。
- ASP.NET MVC把數(shù)據(jù)庫中枚舉項(xiàng)的數(shù)字轉(zhuǎn)換成文字
- 使用EF Code First搭建簡易ASP.NET MVC網(wǎng)站并允許數(shù)據(jù)庫遷移
- asp.net mvc CodeFirst模式數(shù)據(jù)庫遷移步驟詳解
- asp.net實(shí)現(xiàn)的MVC跨數(shù)據(jù)庫多表聯(lián)合動(dòng)態(tài)條件查詢功能示例
- asp.net mvc 從數(shù)據(jù)庫中讀取圖片的實(shí)現(xiàn)代碼
- asp.net MVC 根據(jù)菜單樹類別不同動(dòng)態(tài)加載視圖的實(shí)現(xiàn)步驟
- ASP.NET?MVC使用jQuery的Load方法加載靜態(tài)頁面及注意事項(xiàng)
- ASP.NET MVC懶加載如何逐步加載數(shù)據(jù)庫信息
相關(guān)文章
.NET/ASP.NET Routing路由(深入解析路由系統(tǒng)架構(gòu)原理)
這篇文章主要介紹了.NET/ASP.NET Routing路由(深入解析路由系統(tǒng)架構(gòu)原理),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-07-07
asp.net core3.1cookie和jwt混合認(rèn)證授權(quán)實(shí)現(xiàn)多種身份驗(yàn)證方案
身份驗(yàn)證是確定用戶身份的過程。 授權(quán)是確定用戶是否有權(quán)訪問資源的過程。本文主要介紹了asp.net core3.1cookie和jwt混合認(rèn)證授權(quán)實(shí)現(xiàn)多種身份驗(yàn)證方案,感興趣的可以了解一下2021-09-09
Visual Studio ASP.NET Core MVC入門教程第一篇
這篇文章主要為大家詳細(xì)介紹了Visual Studio ASP.NET Core MVC入門教程的第一篇,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03
ASP.NET MVC驗(yàn)證碼功能實(shí)現(xiàn)代碼
ASP.NET MVC驗(yàn)證碼功能實(shí)現(xiàn)代碼,需要的朋友可以參考一下2013-06-06
win10下vs2015配置Opencv3.1.0詳細(xì)過程
這篇文章主要為大家詳細(xì)介紹了win10下vs2015配置Opencv3.1.0的詳細(xì)過程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-11-11
asp.net實(shí)現(xiàn)從Txt文件讀取數(shù)據(jù)到數(shù)據(jù)視圖的方法
這篇文章主要介紹了asp.net實(shí)現(xiàn)從Txt文件讀取數(shù)據(jù)到數(shù)據(jù)視圖的方法,涉及asp.net針對(duì)文本文件的遍歷操作與DataView的寫入操作相關(guān)技巧,需要的朋友可以參考下2015-12-12
ASP.NET技巧:教你制做Web實(shí)時(shí)進(jìn)度條
ASP.NET技巧:教你制做Web實(shí)時(shí)進(jìn)度條...2006-09-09
.NET CORE動(dòng)態(tài)調(diào)用泛型方法詳解
這篇文章主要為大家詳細(xì)介紹了.NET CORE動(dòng)態(tài)調(diào)用泛型方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08

