C#中Linq延迟执行问题
2014-01-07 18:12
621 查看
本文来自:http://msdn.microsoft.com/zh-cn/library/bb399393(v=vs.110).aspx
http://www.cnblogs.com/zhanglinfan/articles/1457068.htmlhttp://hi.baidu.com/ccitofhxxxbenwq/item/b930bca05b49f57f6cd455c6
延迟加载与立即加载
.NET Framework 4.5其他版本
此主题尚未评级 - 评价此主题
查询某对象时,实际上您只检索请求的对象。 不会同时自动获取相关对象。 (有关更多信息,请参见跨关系查询。)您无法看到相关对象尚未加载这一事实,原因是尝试访问它们时将产生检索它们的请求。
例如,您可能需要查询一组特定的订单,然后偶而向特定客户发送电子邮件通知。 您最初不一定需要检索与每个订单有关的所有客户数据。 您可以使用延迟加载将额外信息的检索操作延迟到您确实需要检索它们时再进行。 请看下面的示例:
C#
VB
Northwnd db = new Northwnd(@"northwnd.mdf"); IQueryable<Order> notificationQuery = from ord in db.Orders where ord.ShipVia == 3 select ord; foreach (Order ordObj in notificationQuery) { if (ordObj.Freight > 200) SendCustomerNotification(ordObj.Customer); ProcessOrder(ordObj); } }
反过来也可能是可行的。 您的应用程序可能必须同时查看客户数据和订单数据。 您了解同时需要这两组数据。 您了解一旦获得结果,您的应用程序就需要每个客户的订单信息。 您不希望一个一个地提交对每个客户的订单的查询。 您真正想要的是将订单数据与客户信息一起检索出来。
C#
VB
Northwnd db = new Northwnd(@"c:\northwnd.mdf"); db.DeferredLoadingEnabled = false; IQueryable<Customer> custQuery = from cust in db.Customers where cust.City == "London" select cust; foreach (Customer custObj in custQuery) { foreach (Order ordObj in custObj.Orders) { ProcessCustomerOrder(ordObj); } }
您还可以在查询中联接客户和订单,方法是构建叉积并将所有相关数据位作为一个大型投影检索出来。 但这些结果并非实体。 (有关更多信息,请参见 LINQ to SQL 对象模型)。 实体是具有标识且您可以修改的对象,而这些结果将是无法更改和持久化的投影。 更糟的是,您将检索到大量的冗余数据,因为在平展联接输出中,对于每个订单,每个客户将重复出现。
您真正需要的是同时检索相关对象的集合的方法。 此集合是关系图的精确剖面,因此您检索到的数据绝不会比您所需要的数据多或少。 为此,LINQ to SQL 提供了 DataLoadOptions,用以立即加载对象模型的某一区域。 方法包括:
LoadWith 方法,用于立即加载与主目标相关的数据。
AssociateWith 方法,用于筛选为特定关系检索到的对象。
一,关于Linq延迟执行问题
var result=from c in Products
where c.Price>500
select c;
foreach(Product p in result){
Console.WriteLine(p.Name);
}
foreach(Product p in result){
Console.WriteLine(p.Name);
}
因此,对于上述程序,两个foreach语句会导致查询被执行两次,这种行为被称作
Linq延迟执行。如果使用不当,会导致各种程序效率问题,比如大量的数据绑定如果做得是Linq延迟执行,程序效率将会大大降低。
改进Linq延迟执行
var result=from c in Products
where c.Price>500
select c;
var list=result.ToList<Product>();
foreach(Product p in result){
Console.WriteLine(p.Name)
}
foreach(Product p in result){
Console.WriteLine(p.Name)
}
通过调用ToList或者ToArray方法,可以直接执行Linq查询,将查询结果缓冲再list变量中。从而可以避免Linq延迟执行的效率问题。
关于Linq中对象引用相等的问题
var result=
from c in db.Categorys
from p in c.Products
where p.ProductId=="FI-01"
select p;
// 第一次查询
Product p1=null;// 映射数据库中的一行(主键为"FI-01")
foreach(var item in result)
{
p1=item;
Console.WriteLine(item.Name);
}
// 第二次查询
Product p2=null;// 映射数据库中的一行(主键为"FI-01")
foreach(var item in result)
{
p1=item;
Console.WriteLine(item.Name);
}
Console.WriteLine(p1==p2);// p1与p2引用相等。 p1==p2相当于//object.ReferenceEquals(p1,p2)
相关文章推荐
- C#_深入理解Linq的延迟执行
- 代码演示 Linq 延迟执行(Deferred Execution) 带来的问题
- C#使用LINQ中Enumerable类方法的延迟与立即执行的控制
- 关于C#3.5用LINQ映射问题!
- LINQ之路 6:延迟执行(Deferred Execution)
- 解决C#中用Oracle执行存储过程返回DataSet的问题
- LINQ 的查询执行何时是延迟执行,何时是立即执行,以及查询的复用
- 关于js延迟执行问题
- Linq to sql:延迟执行
- linq的延迟执行--学习linq的资料和笔记(四)
- 非递归形式的N皇后问题---用C#实现,VS2008可以执行
- Linq 学习(7) 延迟执行 & 查询非泛型集合
- C#执行cmd.exe 不能关闭问题
- C#→关于System.Data.Linq下的Table<TEntity> 泛型类 的问题
- c#关于执行cmd命令,待机问题
- sql server 关于表中只增标识问题 C# 实现自动化打开和关闭可执行文件(或 关闭停止与系统交互的可执行文件) ajaxfileupload插件上传图片功能,用MVC和aspx做后台各写了一个案例 将小写阿拉伯数字转换成大写的汉字, C# WinForm 中英文实现, 国际化实现的简单方法 ASP.NET Core 2 学习笔记(六)ASP.NET Core 2 学习笔记(三)
- [C#]不用IIS直接执行aspx文件中遇到的问题
- 在C# 中Sql 执行超时的问题
- linq 延迟执行带来的困扰