首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

LINQ to SQL 進階:對象加載策略全解析(延遲/預加載/關聯篩選/加載重寫)

     編輯:關於.NET

四大加載模式對比

模式觸發時機適用場景資料庫往返
延遲加載 (默認)訪問導航屬性時不確定是否需要關聯數據多次 (N+1 問題)
預加載 LoadWith主查詢執行時確定需要關聯數據單次 (JOIN)
關聯篩選 AssociateWith預加載時只需關聯數據子集單次 (帶 WHERE 的 JOIN)
加載重寫 (分部方法)加載特定關聯時自定義加載邏輯 (如存儲過程)可控

1. 延遲加載

var custs = from c in db.Customers
            where c.City == "Sao Paulo"
            select c;
// 查詢尚未執行
foreach (var cust in custs) {
    foreach (var ord in cust.Orders) { // 此處觸發新查詢
        // ...
    }
}

優點:按需查詢;缺點:遍歷集合時產生 N+1 次查詢。

2. 預加載:LoadWith

DataLoadOptions ds = new DataLoadOptions();
ds.LoadWith<Customer>(c => c.Orders);
db.LoadOptions = ds;

var custs = from c in db.Customers
            where c.City == "Sao Paulo"
            select c;
// 單次查詢使用 LEFT JOIN 同時獲取 Customers + Orders

3. 關聯篩選:AssociateWith

DataLoadOptions ds = new DataLoadOptions();
ds.AssociateWith<Customer>(c => c.Orders.Where(o => o.ShipVia > 1));
db.LoadOptions = ds;
// 僅預加載 ShipVia > 1 的訂單,但生成多條 SQL (非單一 JOIN)

注意:AssociateWith 配合延遲加載時仍會產生多查詢;配合 LoadWith 可在單查詢中篩選。

4. 組合用法:多層預加載 + 篩選排序

DataLoadOptions ds = new DataLoadOptions();
ds.LoadWith<Customer>(c => c.Orders);
ds.LoadWith<Order>(o => o.OrderDetails);
ds.AssociateWith<Order>(o => o.OrderDetails.OrderBy(od => od.Quantity));
db.LoadOptions = ds;
// 單次查詢獲取 Customer → Orders → OrderDetails,且明細按數量排序

5. 加載重寫:分部方法攔截

// Category 分部類
partial class Category {
    private IEnumerable<Product> LoadProducts(Category category) {
        // 可調用存儲過程或自定義邏輯
        return this.Products
            .Where(p => p.CategoryID == category.CategoryID)
            .Where(p => !p.Discontinued);
    }
}

// 使用時
DataLoadOptions ds = new DataLoadOptions();
ds.LoadWith<Category>(c => c.Products);
db.LoadOptions = ds;
// 加載 Category.Products 時自動調用上述 LoadProducts 方法

最佳實踐建議

  • 明確需要關聯數據 → LoadWith
  • 只需關聯子集 → LoadWith + AssociateWith
  • 複雜加載邏輯 (存儲過程、緩存等) → 分部方法重寫
  • 避免在循環中訪問未預加載的導航屬性 (N+1 殺手)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved