日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Entity Framework 4.1 : 贪婪加载和延迟加载

發布時間:2025/3/15 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Entity Framework 4.1 : 贪婪加载和延迟加载 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這篇文章將討論查詢結果的加載控制。

EF4.1 允許控制對象之間的關系,當我們進行查詢的時候,哪些關系的數據將會被加載到內存呢?所有相關的對象都需要嗎?在一些場合可能有意義,例如,當查詢的實體僅僅擁有一個相關的子實體,但是,多數情況下,你可能只需要加載部分數據,或者你喜歡的話,加載更多的數據。

默認情況下, EF4.1 僅僅加載查詢中涉及的實體,但是它支持兩種特性來幫助你控制加載:

  • 貪婪加載
  • 延遲加載

貪婪加載

對于下面的查詢

using (var context =new MyDomainContext())
{

var orders
= from o in context.Orders.Include("OrderDetails")
where o.CustomerName =="Mac"
select o;

這里我指定加載某些訂單,就是客戶名為 Mac 的客戶的訂單,而且希望相關的訂單明細也一起加載。

你可以這樣查看實際執行的 SQL 查詢

Console.WriteLine(orders.ToString());

實際的 SQL 如下所示:

SELECT
[Project1].[OrderID]AS[OrderID],
[Project1].[OrderTitle]AS[OrderTitle],
[Project1].[CustomerName]AS[CustomerName],
[Project1].[TransactionDate]AS[TransactionDate],
[Project1].[C1]AS[C1],
[Project1].[OrderDetailID]AS[OrderDetailID],
[Project1].[OrderID1]AS[OrderID1],
[Project1].[Cost]AS[Cost],
[Project1].[ItemName]AS[ItemName]
FROM ( SELECT
[Extent1].[OrderID]AS[OrderID],
[Extent1].[OrderTitle]AS[OrderTitle],
[Extent1].[CustomerName]AS[CustomerName],
[Extent1].[TransactionDate]AS[TransactionDate],
[Extent2].[OrderDetailID]AS[OrderDetailID],
[Extent2].[OrderID]AS[OrderID1],
[Extent2].[Cost]AS[Cost],
[Extent2].[ItemName]AS[ItemName],
CASEWHEN ([Extent2].[OrderDetailID]ISNULL) THENCAST(NULLASint) ELS
E
1ENDAS[C1]
FROM[dbo].[Orders]AS[Extent1]
LEFTOUTERJOIN[dbo].[OrderDetails]AS[Extent2]ON[Extent1].[OrderID]
=[Extent2].[OrderID]
WHERE N'Mac'=[Extent1].[CustomerName]
)
AS[Project1]
ORDERBY[Project1].[OrderID]ASC, [Project1].[C1]ASC

EF4.1 生成的 SQL 不是特別易讀,但是這個查詢你應該能夠看懂,訂單明細被一起加載了。

這帶來了一個關于貪婪加載的問題:查詢效率。如果你執行這樣的查詢來獲取訂單和訂單明細,也可以變成寫出等效的查詢語句,如果喜歡的話,可以更加聰明地寫出返回兩個查詢結果的查詢,一個是訂單,另外一個是訂單明細。這應該更加有效,因為你不需要為每一個訂單明細重復訂單的信息。由于一些原因,EF 并不支持。記住這一點,因為這很容易使性能變差。

無論如何,你還可以在查詢中包含更多的子集。

var orders =from o in context.Orders.Include("OrderDetails").Include("Businesses")
where o.CustomerName == "Mac"
select o;

延遲加載

另外一個特性就是延遲加載,默認情況下,延遲加載被支持,如果你希望禁用它,必須顯式聲明,最好的位置是在 DbContext 的構造器中。

public MyDomainContext()
{
this.Configuration.LazyLoadingEnabled
= false;
}

這樣延遲加載就如你所愿了。當查詢一個實體集的時候,相關的子實體也一并加載。

當 EF 訪問實體的子實體的時候是如何工作的呢?你的集合是 POCO 的集合,所以,在訪問的時候沒有事件發生,EF 通過從你定義的實體派生一個動態的對象,然后覆蓋你的子實體集合訪問屬性來實現。這就是為什么需要標記你的子實體集合屬性為 virtual 的原因。

public class Order
{
publicint OrderID { get; set; }
public string OrderTitle { get; set; }
public string CustomerName { get; set; }
publicDateTime TransactionDate { get; set; }
public virtual List<OrderDetail> OrderDetails { get; set; }
public virtual List<Business> Businesses { get; set; }
}

總結一下兩種加載方式的特點

貪婪加載:

  • 減少數據訪問的延遲,在一次數據庫的訪問中返回所有的數據。
  • 你需要知道你將作什么,并且顯式聲明

延遲加載:

  • 非常寬容,因為只在需要的時候加載數據,不需要預先計劃
  • 可能因為數據訪問的延遲而降低性能,考慮到每訪問父實體的子實體時,就需要訪問數據庫。

現在,什么時候我們應該使用哪種機制?我的建議是:除非需要循環中加載數據,我使用延遲加載。這樣的話,可能會造成2-3 次服務器的查詢,但是仍然是可以接受的,特別是考慮到貪婪加載的效率問題。

轉載于:https://www.cnblogs.com/tianboblog/p/3229228.html

總結

以上是生活随笔為你收集整理的Entity Framework 4.1 : 贪婪加载和延迟加载的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。