Linq to Sql學習總結4
阿新 • • 發佈:2018-11-20
延遲執行:
Linq to sql 查詢句法在定義時並不會執行,只有在呼叫的時候才會執行(執行T_Sql查詢),每呼叫一次就會執行一次。對於需要多次呼叫的情況,可以使用ToList()方法先把結果集儲存下來。
DataLoadOptions
DataLoadOptions options = new DataLoadOptions(); //載入Product的同時把Order_Details也加載出來 options.LoadWith<Product>(p => p.Order_Details); //定義Order_Details的載入條件 options.AssociateWith<Product>(p => p.Order_Details.Where(od => od.Quantity > 80)); ctx.LoadOptions = options;
//若沒有設定DataLoadOptions載入選項: /** 此段程式碼塊中每一次輸出o.Quantity都會執行一次sql語句操作,外層迴圈每執行一次裡層就會執行一次查詢 **/ /** SELECT [t0].[OrderID], [t0].[ProductID], [t0].[UnitPrice], [t0].[Quantity], [t0].[Discount] FROM [dbo].[Order Details] AS [t0] WHERE [t0].[ProductID] = @p0 這樣的查詢被執行了N次 **/ //若設定了DataLoadOptions載入選項: DataLoadOptions option = new DataLoadOptions(); //載入Products實體類的同時也把Products對應的Order_Details加載出來 option.LoadWith<Products>(p => p.Order_Details); ctx.LoadOptions = option; /** 對於此段程式碼塊中的查詢句法只會執行一次T_SQL操作 **/ /** 生成Products LEFT OUT JION Order_Details的sql語句 **/ foreach (var p in (from p in ctx.Products select p)) { if (p.UnitPrice > 10) { foreach (var o in (from o in p.Order_Details select o)) { Response.Write(o.Quantity + "<br />"); } } } /****/ //DataLoadOptions限制:DataLoadOptions對於一對多的關係只支援載入一次 DataLoadOptions options = new DataLoadOptions(); options.LoadWith<Customer>(c => c.Orders); //Order left out join Order_Details語句會被多次執行 options.LoadWith<Orders>(o => o.Order_Details); ctx.LoadOptions = options; IEnumerable<Customer> customers = ctx.Customers.ToList<Customer>(); //而對於多對1的關係,Linq to sql對於DataLoadOptions沒有限制 DataLoadOptions options = new DataLoadOptions(); options.LoadWith<Product>(c => c.Category); options.LoadWith<Product>(c => c.Order_Details); options.LoadWith<Order_Detail>(o => o.Order); ctx.LoadOptions = options; IEnumerable<Product> products = ctx.Products.ToList<Product>(); /** 使用DataLoadOptions多次載入實體集時對記憶體消耗很大,還是少用,建議複雜的載入查詢使用儲存過程 **/
主鍵快取:
//Linq To Sql會快取查詢句法中只使用了主鍵查詢出的結果集,下一次若還是採用相同主鍵進行查詢, //則直接會從快取中取結果集,對應的T_SQL操作也只會執行一次(只會在資料庫沒有更新的情況下取快取) //若資料庫更新了會通知DataContent物件,DataContent類繼承了用於通知更新的類管理通知 Customers c1 = ctx.Customers.Single(customer => customer.CustomerID == "ANATR"); c1.ContactName = "zhuye"; //在給c1.ContactName賦值的時候才會執c1,所以實際上快取中c1.ContactName的值為"zhuye" Customers c2 = ctx.Customers.Single(customer => customer.CustomerID == "ANATR"); //此時資料庫並沒有更新,所以快取內容也沒有更新 Response.Write(c2.ContactName);
新增外部物件:
//DataContext隔離:可以通過Attach()方法加入外部物件 //外部物件:一般指跨域傳過來的物件或通過webservice傳過來的物件或者非託管程式碼下的物件,不受當前應用程式域管理,是detached的 //物件在實體類中定義的主鍵屬性必須新增特性IsVersion=true,才能新增外邊物件 Customers customers = new Customers { CustomerID = "ALFKI", ContactName = "zhuye", CompanyName = "1111" }; ctx.Customers.Attach(customers, true); ctx.SubmitChanges();
其它:
//下面的程式碼會導致提交N次DELETE操作 var query = from c in ctx.Customers select c; ctx.Customers.DeleteAllOnSubmit(query); ctx.SubmitChanges(); //對於批量操作應使用sql命令(批量更新也是) string sql = string.Format("DELETE FROM {0}", ctx.Mapping.GetTable(typeof(Customers)).TableName); ctx.ExecuteCommand(sql);