LINQ to SQL語句(17)之對象加載
系列文章導航:
LINQ to SQL語句(2)之Select/Distinct
LINQ to SQL語句(3)之Count/Sum/Min/Max/Avg
LINQ to SQL語句(6)之Group By/Having
LINQ to SQL語句(7)之Exists/In/Any/All/Contains
LINQ to SQL語句(8)之Concat/Union/Intersect/Except
LINQ to SQL語句(9)之Top/Bottom和Paging和SqlMethods
LINQ to SQL語句(12)之Delete和使用Attach
LINQ to SQL語句(14)之Null語義和DateTime
LINQ to SQL語句(19)之ADO.NET與LINQ to SQL
對象加載
延遲加載
在查詢某對象時,實際上你只查詢該對象。不會同時自動獲取這個對象。這就是延遲加載。
例如,您可能需要查看客戶數據和訂單數據。你最初不一定需要檢索與每個客戶有關的所有訂單數據。其優點是你可以使用延遲加載將額外信息的檢索操作延遲到你確實需要檢索它們時再進行。請看下面的示例:檢索出來CustomerID,就根據這個ID查詢出OrderID。
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) { //同時查看客戶數據和訂單數據 } }
語句描述:原始查詢未請求數據,在所檢索到各個對象的鏈接中導航如何能導致觸發對數據庫的新查詢。
預先加載:LoadWith 方法
你如果想要同時查詢出一些對象的集合的方法。LINQ to SQL 提供了 DataLoadOptions用于立即加載對象。方法包括:
LoadWith 方法,用于立即加載與主目標相關的數據。
AssociateWith 方法,用于篩選為特定關系檢索到的對象。
使用 LoadWith方法指定應同時檢索與主目標相關的哪些數據。例如,如果你知道你需要有關客戶的訂單的信息,則可以使用 LoadWith 來確保在檢索客戶信息的同時檢索訂單信息。使用此方法可僅訪問一次數據庫,但同時獲取兩組信息。
在下面的示例中,我們通過設置DataLoadOptions,來指示DataContext在加載Customers的同時把對應的Orders一起加載,在執行查詢時會檢索位于Sao Paulo的所有 Customers 的所有 Orders。這樣一來,連續訪問 Customer 對象的 Orders 屬性不會觸發新的數據庫查詢。在執行時生成的SQL語句使用了左連接。
NorthwindDataContext db = new NorthwindDataContext(); DataLoadOptions ds = new DataLoadOptions(); ds.LoadWith<Customer>(p => p.Orders); db.LoadOptions = ds; var custs = ( from c in db2.Customers where c.City == "Sao Paulo" select c); foreach (var cust in custs) { foreach (var ord in cust.Orders) { Console.WriteLine("CustomerID {0} has an OrderID {1}.", cust.CustomerID, ord.OrderID); } }
語句描述:在原始查詢過程中使用 LoadWith 請求相關數據,以便稍后在檢索到的各個對象中導航時不需要對數據庫進行額外的往返。
延遲加載:AssociateWith方法
使用 AssociateWith 方法指定子查詢以限制檢索的數據量。
在下面的示例中,AssociateWith 方法將檢索的 Orders 限制為當天尚未裝運的那些 Orders。如果沒有此方法,則會檢索所有 Orders,即使只需要一個子集。但是生成SQL語句會發現生成了很多SQL語句。
NorthwindDataContext db2 = new NorthwindDataContext(); DataLoadOptions ds = new DataLoadOptions(); ds.AssociateWith<Customer>( p => p.Orders.Where(o => o.ShipVia > 1)); db2.LoadOptions = ds; var custs = from c in db2.Customers where c.City == "London" select c; foreach (var cust in custs) { foreach (var ord in cust.Orders) { foreach (var orderDetail in ord.OrderDetails) { //可以查詢出cust.CustomerID, ord.OrderID, ord.ShipVia, //orderDetail.ProductID, orderDetail.Product.ProductName } } }
語句描述:原始查詢未請求數據,在所檢索到各個對象的鏈接中導航如何以觸發對數據庫的新查詢而告終。此示例還說明在延遲加載關系對象時可以使用 Assoicate With 篩選它們。