Entity Framework 小技巧四 —— 如何使用NoTracking查询得到Detached状态的实体?

有时我们的实体只需要显示,无需更新,所以为了提高性能,我们不需要实体被EF context追踪。此时可以使用NoTracking的查询来得到实体,这样实体的状态会是Detached状态。

 

在EF3.5 SP1和EF 4中,我们可以这样来进行NoTracking查询:

using  (var context  =   new  MyObjectContext())
{
    context.People.MergeOption 
=  System.Data.Objects.MergeOption.NoTracking;
    var list 
=  context.People.Where(p  =>  PersonID  >   100 ).ToList();
}

或使用ExecuteStoreQuery API来直接调用SQL命令来得到实体:

using  (var context  =   new  MyObjectContext())
{
    var query 
=  context.ExecuteStoreQuery < Parent > ( " SELECT * FROM Parent WHERE Parent.ParentID > @ID " " TestDBEntities.Parents " System.Data.Objects.MergeOption.NoTracking new  SqlParameter( " @ID " 100 ));
}

或使用Load方法得到相关实体:

using  (var context  =   new  MyObjectContext())
{
    context.ContextOptions.LazyLoadingEnabled 
=   false ;
    var person 
=  context.People.First();
    person.Courses.Load(System.Data.Objects.MergeOption.NoTracking);
}


在EF 4.1中,我们可以使用新增的AsNoTracking方法:

using  (var context  =   new  MyDbContext())
{
     var people 
=  context.People.Where(p  =>  p.PersonID  >   100 ).AsNoTracking().ToList();
}

 

这里的AsNoTracking方法内部调用了过去的ObjectQuery.MergeOption来实现NoTracking查询。此方法(DbHelpers.CreateNoTrackingQuery)是AsNoTracking方法的核心:

public   static  IQueryable CreateNoTrackingQuery(ObjectQuery query)
{
    IQueryable queryable 
=  query;
    ObjectQuery query2 
=  (ObjectQuery) queryable.Provider.CreateQuery(queryable.Expression);
    query2.MergeOption 
=  MergeOption.NoTracking;
    
return  query2;
}

 

再为大家介绍NoTracking得到的Detached实体的一个小问题。由NoTracking查询得到的实体和我们直接调用Detach方法得到的实体不同。前者内部会仍然保留一个对当前context的引用,以便在调用Load方法可以explicitly load相关的实体。而后者则完全脱离了相应的context,所以属于真正的Detached状态。细心的读者可能会觉得NoTracking得到的Detached实体会导致context一直被引用,从而不能及时被垃圾处理(GC)。确实,这个被产品组证实是by design的,如果context不被引用,则explicit load则无法被支持。有关这个问题的更详细信息,请参看:

http://connect.microsoft.com/VisualStudio/feedback/details/507482/entity-framework-query-with-mergeoption-notracking-result-memory-leak

http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/906c0cad-840b-4eb8-ba11-5348d407df73 (我前年处理的一个MSDN帖子)

 

 

PS1:这里为大家带来一个好消息:微软一站式实例代码库(Microsoft All-In-One Code Framework)即日起正式迁移至MSDN代码库了,新的平台会帮您更轻松地解决开发难题、节省更多时间、获得更友好的用户体验。本人作为这个项目的元老,见到我们已拥有600多个经典的代码实例,甚感欣慰啊!  更详细信息,请看http://msdn.microsoft.com/zh-cn/hh124104.aspx?ocid=ban-f-cn-loc-OC201104-MSDN

最新的代码浏览器也发布啦!为大家带来了更多很cool的功能,比如1)代码按需下载 2)实例集中化管理  3)自动更新

http://blog.csdn.net/MSCodeSample/archive/2011/04/18/6331382.aspx 

之后我将尽力为大家带来更多有关EF的代码实例以及相关的介绍!



PS2:同事开发了一个很cool的MSDN论坛桌面小工具,绝对给力!欢迎使用!(我也出了不少力啊


也欢迎到MSDN中文论坛ADO.NET与LINQ论坛来提问EF的问题啊,可以试试直接报我的名字Michael Sun,哈哈! 

 

如需转发请注明原文出处,谢谢: http://www.cnblogs.com/LingzhiSun/archive/2011/04/27/EF_Trick4.html

转载于:https://www.cnblogs.com/LingzhiSun/archive/2011/04/27/EF_Trick4.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值