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

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

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

来源: www.dedecms8.com 编辑:织梦吧 时间:2012-06-27点击:

01 public void Load()
02 {
03     if (this.HasSource)
04     {
05         ItemList<TEntity> entities = this.entities;
06         this.entities = new ItemList<TEntity>();
07         foreach (TEntity local in this.source)
08         {
09             this.entities.Add(local);
10         }
11 ...
12     }
13 }

再进一步就要追溯到 System.Data.Linq.CommonDataServices.GetDeferredSourceFactory(MetaDataMember) 和System.Data.Linq.Mapping.EntitySetValueAccessor。当DataContext对象初始化模型信息时,会调用GetDeferredSourceFactory为指定属性生成相应的DeferredSourceFactory对象,该工厂对象通过 CreateDeferredSource()生成延迟源对象。在执行查询操作时,DataContext将会调用每个对象的EntitySet属性的 SetSource方法,为每一个EntitySet绑定延迟源,由延迟源来调用DataContext实现延迟加载,这样就实现了EntitySet和 DataContext的解耦,让POCO类也变智能了。对于EntitySet,当执行延迟加载后,延迟源将被清空,并且相应的已加载标志也将设为 true。

接下来我们验证一下,为了方便示例我只保留Customer类的Orders作为唯一的Association属性:(文章最后会给出代码下载,有兴趣可以照着验证)

01 Customer customer = null;
02
03 using (var context = CreateNorthwnd())
04 {
05     customer = context.Customers.First();
06     // forces to load order association
07     customer.Orders.Count.Dump();
08 }
09  
10 customer.City = "Beijing";
11  
12 using (var context = CreateNorthwnd())
13 {
14     context.Customers.Attach(customer);
15     context.SubmitChanges();
16 }

别急,还是错的!虽然customer.Orders.Count的调用让customer.Orders被加载,但Order对象还包含几个未被加载的Association属性,你把Order对象的Association属性定义去掉就对了!

剖析到这里你明白为什么当存在Association或嵌套Association未被赋值或加载,且延迟源不为空时会抛出异常了么?这是因为和需要Attach的对象一样,延迟源关联的DataContext对象已经被销毁了,延迟源无法在加载数据,所以DataContext拒绝关联这样的对象。

 

说了那么多,是为了让大家能够明白为什么会产生异常,解决的方法很简单,不需要修改实体的定义,同时也是个人认为LINQ2SQL最佳实践之一:

About D8

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