LINQ查询优化:避免SQL往返

感谢所有有意或无意中帮助成为微软MVP的人,希望能不负众望。在本节中,将了解LINQ的往返问题,以及如何使用‘DataLoadOptions’来克服这些问题。LINQ to SQL的一个最大问题是它对每个对象都会触发SQL查询,这对性能有很大影响。在本文中,将看到如何通过一次SQL查询获取所有数据。

LINQ基础

本文假设已经了解如何使用LINQ来丰富实体对象。如果不了解LINQ to SQL映射的基础知识,可以阅读文章来理解基本的LINQ概念。

客户、地址和电话的LINQ实体

首先,让尝试了解LINQ查询是如何工作的,然后将看到往返是如何发生的。假设有以下数据库设计,其中包含3个表——客户、地址和电话。客户和地址之间是一对多关系,而地址表和电话之间是一对一关系。已经根据表设计创建了三个实体:

  • ClsCustomerWithAddresses
  • ClsAddresses
  • ClsPhone

使用‘EntitySet’和‘EntityRef’定义了它们之间的关系。从表中填充实体对象的数据是一个5步过程。首先,使用连接字符串创建datacontext连接,创建LINQ查询,然后开始浏览客户、地址和电话。

分析LINQSQL往返

好的,现在已经分析了执行LINQ查询需要5个步骤,让尝试弄清楚在哪个步骤LINQ查询实际上向数据库触发SQL。将运行上述LINQ代码,并使用SQL profiler进行分析。为了避免捕获到大量的SQL Server噪音,只启用了RPC和SQL批处理事件。

现在,当运行查询时,会发现以下事情:

  • 实际的SQL执行发生在foreach语句遍历LINQ对象时。
  • 第二个非常惊人的事情是,对于每个实体,都会向SQLServer触发一个单独的查询。例如,对于客户,触发了一个查询,然后为地址和电话分别触发了单独的查询,以丰富实体对象。换句话说,有很多往返。

使用DataLoadOptions避免往返

可以指示LINQ引擎使用‘DataLoadOptions’加载所有对象。以下是启用‘DataLoadOptions’的步骤。

  1. 创建数据上下文类:
  2. DataContext objContext = new DataContext(strConnectionString);
  3. 创建‘DataLoadOption’对象:
  4. DataLoadOptions objDataLoadOption = new DataLoadOptions();
  5. 使用LoadWith方法,需要定义想要在一次SQL中加载客户和地址。
  6. objDataLoadOption.LoadWith<clsCustomerWithAddresses>(clsCustomerWithAddresses => clsCustomerWithAddresses.Addresses);
  7. 每个地址对象都有电话对象,所以还定义了说每个地址对象的电话对象应该在一次SQL中加载。
  8. objDataLoadOption.LoadWith<clsAddresses>(clsAddresses => clsAddresses.Phone);
  9. 定义的任何加载选项,都需要使用‘LoadOptions’属性设置到数据上下文对象。
  10. objContext.LoadOptions = objDataLoadOption;
  11. 最后,准备查询:
  12. var MyQuery = from objCustomer in objContext.GetTable<clsCustomerWithAddresses>() select objCustomer;
  13. 开始遍历对象:
  14. 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相比,正确地进行了连接。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485