步步深入EF(二) 延遲載入

2021-06-27 17:32:43 字數 4486 閱讀 5089

ef延遲載入:就是使用lamabda表示式或者linq 從 ef實體物件中查詢資料時,ef並不是直接將資料查詢出來,而是在用到具體資料的時候才會載入到記憶體。

很多資料講的ef原理,只是延遲查詢資料,是這樣嗎?ef本質究竟是什麼呢?

1、延遲生成

sql語句

生成的sql語句不確定

2、按需載入

針對於外來鍵屬性而言,

ef會在用到這個外來鍵屬性時才會去查詢對應的表

先來介紹幾個概念:

概念一:entityframework的由來

用過ef的人都知道,我們的程式中都會引用它。它是微軟自帶的嗎?如果是,為什麼不直接封裝在framework中,而是需要去引用;如果不是,那為什麼會建立ef模型時自動建立它。

解釋:entity

framework在建立ef模型中,

自動複製

,是擴充套件出來的

,用時複製過來,相當於

微軟開發的第三方程式集

,不屬於

framework

為什麼不放在

framework中?

老版本中不存在ef

,新版本才有ef

.為了相容,

現在老版本只需要將其引入即可,不需要重新改動。

概念二:標準查詢運算子中的where含義

(1)普通集合中的where子句

(2)ef中dbset返回集合的where子句

//集合的標準查詢運算子方法,是來自於system.linq.enumerable裡給ienumerable介面新增的擴充套件方法(即時)

listliststr = new list();

liststr.where(i=>liststr.contains(i));

//上下文中dbset返回的集合(延時)

listorder = db.order_info.where(u => u.orderid == 1).tolist();

區別:普通集合的標準查詢運算子方法,來自於system.linq.

enumerable

裡的擴充套件方法,給

ienumerable

介面新增擴充套件方法,

ef裡的dbset標準查詢運算子方法,來自於system.linq.

queryable

裡,給iqueryable介面新增擴充套件方法,

iqueryable介面

是非常特殊,正是因為這個介面,才支援的延遲查詢,dbset實現iqueryable介面

聯絡:

iqueryable和

ienumerable

是兩套查詢策略,封裝好的方法相同,但具體實現不同。乙個是即時查詢,另乙個是延時查詢。

概念三:延遲基於iqueryable

本質基於iqueryable擴充套件類dbq

uery,為iqueyable提供了很多擴充套件方法

1

、延遲生成

sql語

//延遲查詢

dbqueryi = db.order_info.where(u => u.orderid == 1) as dbquery;

order_info order1 = i.firstordefault();

console.writeline();

在這裡我們為什麼要使用dbquery來接收呢?

首先我們來看使用

db.order_info.where()

來獲取文章列表的時候,where()方法給我們返回乙個什麼型別的物件呢?我們把滑鼠放在where()方法上後,會發現where會返回給我們乙個iqueryable的泛型介面物件,如下圖:

那我們是不是需要使用iqueryable物件來接收獲取的物件呢,**如下

//where()方法返回乙個iquery的介面  

可以看到query已經取到值,但根據物件導向的原則,介面不能直接例項化,但我們的**有沒有報錯,為社麼呢?

根據物件導向的黎克特制替換原則,這裡實際上是返回了乙個iqueryable物件的子類物件。

黎克特制替換原則,子類物件可以賦值給父類物件。也就是說子類可以替換父類出現的地方。但是父類物件一定不可以替換子類物件。

也就是說where()方法返回了乙個iqueryable介面的子類物件,並且賦值給了它的父類物件iqueryable。

那麼where()到底返回了乙個什麼樣的iqueryable的子類物件呢?

再次看上面的局變數視窗中query的返回值型別為,如下圖:

我們可以很明顯的看出,query的返回型別為dbquery型別。

那我們就用dbquery來接收物件,**如下:

dbquery

i = db.order_info.where(u => u.orderid == 1) as

dbquery

;因為where()方法返回的是iqueryable物件,所以要把物件轉換成dbquery物件;

查詢訂單表中訂單1的建立日期

dbquery

query = db.order_info;

//獲取訂單表裡的第乙個訂單

order_info order = query.firstordefault();

//獲取這個訂單的建立日期

執行第一條語句:

執行第二條語句:order_info

order = query.firstordefault();

我們只是用到訂單資訊時,才去資料庫查詢第一條訂單的資訊

2、按需載入

ef使用前:當遇到主外來鍵相互關聯的表,當需要從表中的資料時,我們必須通過主表進行查詢。而我們只是需要從表資料,而必須關聯到主表。這種方式是低效的。

ef使用後:我們只需要查詢數從表的資料即可

查詢訂單表中產品1的相關資訊

dbquery

<

order_detail

> query = db.order_

detail

;

//獲取訂單表裡的第乙個訂單

order_

detail

order = query.firstordefault();

//獲取這個訂單的建立日期

if (order != null) 

可直接查詢產品表中的資料

三、好處

1、生成一條語句

(用的時候

,根據條件拼成

sql語句

)2、不受主表約束,提高效率

情況1:是針對產品表中的資料進行檢索再排序

db.order_detail.where(u => u.orderid == 1).orderby(u=>u.productid)

情況2:是針對檢索出來的list集合進行排序

db.order_detail.where(u => u.orderid == 1).tolist().orderby(u=>u.productid)

情況1為延時查詢,根據拼出的sql語句進行查詢;情況2為即時查詢。

以上只是只是簡單的介紹ef的延遲載入,文中還有很多需要在學習過程中進一步完善,下篇博文會對延遲載入的優化進行深入闡述

步步深入ef(三)—優化延遲載入

步步深入EF(一) EF原理

一 什麼是ef?實體架構 entity framework 是微軟以來 ado.net 為基礎開發出來的物件關係對映 orm 解決方案,它解決了物件持久化問題,將程式設計師從編寫麻煩的 sql語句中解放出來。優點 支援多種資料庫 microsoft sql server oracle 和db2 等 ...

EF延遲載入 懶載入

關於ef懶載入英文翻譯lazyload也俗稱延遲載入 只有是 導航屬性 並且 類是public 字段必須用virtual 才能用延遲載入,ef預設是延遲載入的,什麼是延遲載入呢?延遲載入就是當需要用到集合的時候才會去資料庫取資料,有點是什麼呢?優點就是按需取資料提高了載入的速度,缺點是需要多次執行s...

EF 延遲載入技術

延遲載入 優點 只在需要的時候載入資料,不需要預先計畫,避免了各種複雜的外連線 索引 檢視操作帶來的低效率問題 使用方式 兩步 第一 在需要延遲載入的屬性前加上virtual 該屬性的型別可以是任務的集合型別icolloct或者是0 1.1關聯屬性。如 publicvirtuallistproduc...