1. 程式人生 > >Linq to Sql學習總結4

Linq to Sql學習總結4

延遲執行:

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);