• [织梦吧]唯一域名:www.dedecms8.com,织梦DedeCMS学习平台.

当前位置: > 编程与数据库 > net编程 >

LINQ那些事儿(9)-解析Table<T>.Attach引发的异常和解决方法(3)

来源: www.dedecms8.com 编辑:织梦吧 时间:2012-06-27点击:
再看看trackedObject.HasDeferredLoaders做了什么:

01 internal override bool HasDeferredLoaders
02 {
03     get
04     {
05         foreach (MetaAssociation association in this.Type.Associations)
06         {
07             if (this.HasDeferredLoader(association.ThisMember))
08             {
09                 return true;
10             }
11         }
12         foreach (MetaDataMember member in from p in this.Type.PersistentDataMembers
13             where p.IsDeferred && !p.IsAssociation
14             select p)
15         {
16             if (this.HasDeferredLoader(member))
17             {
18                 return true;
19             }
20         }
21         return false;
22     }
23 }

很快就要找到关键点了,在看看this.HasDeferredLoader:

01 private bool HasDeferredLoader(MetaDataMember deferredMember)
02 {
03     if (!deferredMember.IsDeferred)
04     {
05         return false;
06     }
07     MetaAccessor storageAccessor = deferredMember.StorageAccessor;
08     if (storageAccessor.HasAssignedValue(this.current) || storageAccessor.HasLoadedValue(this.current))
09     {
10         return false;
11     }
12     IEnumerable boxedValue = (IEnumerable) deferredMember.DeferredSourceAccessor.GetBoxedValue(this.current);
13     return (boxedValue != null);
14 }

答案揭晓:storageAccessor.HasAssignedValue检测了Association属性是否被赋值(针对 EntityRef),storageAccessor.HasLoadedValue检测了Association属性是否已被加载(针对 EntitySet),如果没有任何的赋值或加载,并且由GetBoxedValue获取的延迟源对象(DeferredSource)不为空,则抛出异常。

要解释Attach为什么在这种情况下会抛出异常?首先要弄明白延迟源对象,这是LINQ2SQL实现延迟加载的关键。在延迟加载的模式 (DataContext.DeferredLoading=true)下,EntitySet和EntityRef属性只有当被访问时,才会产生数据库的查询。以EntitySet为例,当调用GetEnumerator()时:

1 public IEnumerator<TEntity> GetEnumerator()
2 {
3     this.Load();
4     return new Enumerator<TEntity>((EntitySet<TEntity>) this);
5 }

 

this.Load中调用了延迟源进行数据的加载:

About D8

  • ©2014 织梦吧(d8) DedeCMS学习交流平台
  • 唯一网址 www.DedeCMS8.com 网站地图
  • 联系我们 1170734538@qq.com ,  QQ