感谢所有有意或无意中帮助成为微软MVP的人,希望能不负众望。在本节中,将了解LINQ的往返问题,以及如何使用‘DataLoadOptions’来克服这些问题。LINQ to SQL的一个最大问题是它对每个对象都会触发SQL查询,这对性能有很大影响。在本文中,将看到如何通过一次SQL查询获取所有数据。
本文假设已经了解如何使用LINQ来丰富实体对象。如果不了解LINQ to SQL映射的基础知识,可以阅读文章来理解基本的LINQ概念。
首先,让尝试了解LINQ查询是如何工作的,然后将看到往返是如何发生的。假设有以下数据库设计,其中包含3个表——客户、地址和电话。客户和地址之间是一对多关系,而地址表和电话之间是一对一关系。已经根据表设计创建了三个实体:
使用‘EntitySet’和‘EntityRef’定义了它们之间的关系。从表中填充实体对象的数据是一个5步过程。首先,使用连接字符串创建datacontext连接,创建LINQ查询,然后开始浏览客户、地址和电话。
好的,现在已经分析了执行LINQ查询需要5个步骤,让尝试弄清楚在哪个步骤LINQ查询实际上向数据库触发SQL。将运行上述LINQ代码,并使用SQL profiler进行分析。为了避免捕获到大量的SQL Server噪音,只启用了RPC和SQL批处理事件。
现在,当运行查询时,会发现以下事情:
可以指示LINQ引擎使用‘DataLoadOptions’加载所有对象。以下是启用‘DataLoadOptions’的步骤。
DataContext objContext = new DataContext(strConnectionString);
DataLoadOptions objDataLoadOption = new DataLoadOptions();
objDataLoadOption.LoadWith<clsCustomerWithAddresses>(clsCustomerWithAddresses => clsCustomerWithAddresses.Addresses);
objDataLoadOption.LoadWith<clsAddresses>(clsAddresses => clsAddresses.Phone);
objContext.LoadOptions = objDataLoadOption;
var MyQuery = from objCustomer in objContext.GetTable<clsCustomerWithAddresses>() select objCustomer;
foreach (clsCustomerWithAddresses objCustomer in MyQuery) {
Response.Write(objCustomer.CustomerName + "<br>");
foreach (clsAddresses objAddress in objCustomer.Addresses) {
Response.Write("===Address:- " + objAddress.Address1 + "<br>");
Response.Write("========Mobile:- " + objAddress.Phone.MobilePhone + "<br>");
Response.Write("========LandLine:- " + objAddress.Phone.LandLine + "<br>");
}
}
现在,如果运行代码,LINQ将执行一次SQL,并且与之前显示的每个对象3次SQL相比,正确地进行了连接。