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);
原文地址:https://www.cnblogs.com/JDotNet/p/3308771.html