LINQ-to-SQL那點事~關于延時加載的性能,微軟給出了不錯的解決方案
LINQ-to-SQL雖然已經屬于過去事了,但由于歷史原因,還是要關注一下它,呵呵,當微軟推出linq to sql之后,最吸引開發者的地方可能就是可視化的數據模型,靈活可控的分部方法及神神秘秘的延時加載了,呵呵!今天主要再總結一個linq to sql中的延時加載!
對于數據上下文DataContext來說,它有一個屬性叫做DeferredLoadingEnabled,它的默認值為true,意思是開啟模型的延時加載功能,例如:當你有一個對象Order_info,它有關系表Order_Detail,它們之間為一對多的關系,這在dbml模型中用EntitySet<T>來表示,意為實體的集合。而開啟模型的延時加載功能時,只要你查詢出Order_Info后,如果在前臺使用到了Order_Detail,系統就會將Order_Detail的相關數據也查詢出來,聽上去不錯,看代碼:
@foreach (var item in Model) { <p> @item.OrderID @item.CreateDate </p> if (item.Order_Detail.Count > 0) { foreach (var detail in item.Order_Detail) { <p style="margin: 10px;">@detail.OrderID @detail.ProductName</p> } } }
產生的SQL代碼:
注意,當前臺對Order_Detail有需要時,系統會產生查詢Order_Detail的代碼,如果你的10條Order_Info記錄,那么,系統會向SQLSERVER發送10條語句
,這讓我們感覺到了一點壞味道,沒錯,使用延時加載不但沒有提高性能,反爾加大了數據庫的交互,事實上,我可能不是微軟的本意,可能是我們誤會了DeferredLoadingEnabled的用意,呵呵!
DeferredLoadingEnabled使用場合:對于單條記錄可以使用,對于集合對象不應該使用它
Linq To Sql對于集合對象的導航屬性進行延時加載,提供了自己的解決方案
小插曲,一般我們建立DBML模型后,如果希望改它的代碼部分我們一般不會在原文件上改,因為重新生成數據模型后,你改的代碼就被覆蓋了,而我們的做法是新建一個類文件,它與DBML模型文件的數據上下文對象同名(微軟為我們建立的上下文類是partial的,人家已經為咱們預留出接口了,呵呵),如果希望在數據上下文被建立時執行代碼,可以在分部方法OnCreate里作文章(注意默認構造方法已經被原類占用,所以你的分部類不能再定義一個空構造方法了,呵呵)。
DataLoadOptions 對象為我們提供了立即加載模式,它所產生的SQL語句是我們可以接受的,但它不會按需查詢了,即將order_info和order_detail進行join
查詢并直接返回數據,呵呵。
這種方法只在分部方法OnCreate中定義即可,你的DAL實現層,BLL業務組合層,WEB展現層的代碼都不用調整,呵呵。
partial void OnCreated() { // this.DeferredLoadingEnabled = false;//關閉延時加載 #region 優化后的延時加載,對某個對象進行延時加載 DataLoadOptions dl = new DataLoadOptions(); dl.LoadWith<Order_Info>(p => p.Order_Detail); this.LoadOptions = dl; #endregion }
而這種立即加載所產生的SQL語句是我們可以接受的,看圖:
它解釋成的SQL語句也是我們熟悉的,看代碼:
SELECT [t0].[OrderID], [t0].[UserID], [t0].[CreateDate], [t1].[OrderDetailID], [t1].[OrderID] AS [OrderID2], [t1].[ProductID], [t1].[ProductName], ( SELECT COUNT(*) FROM [dbo].[Order_Detail] AS [t2] WHERE [t2].[OrderID] = [t0].[OrderID] ) AS [value] FROM [dbo].[Order_Info] AS [t0] LEFT OUTER JOIN [dbo].[Order_Detail] AS [t1] ON [t1].[OrderID] = [t0].[OrderID] ORDER BY [t0].[OrderID], [t1].[OrderDetailID]
恩,看來linq to sql知所以性能低下,不是它本身的問題,而是我們對它不夠了解呀,呵呵!
浙公網安備 33010602011771號