延迟执行:
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);