最新更新 sitemap 网站制作设计本站搜索
网页设计
国外网站 韩国网站 个人主页 手提袋设计 CSS 网页特效 平面设计 网站设计 Flash CMS技巧 服装网站 php教程 photoshop 画册 服务器选用 数据库 Office
虚拟主机 域名注册 云主机 网页设计 客服QQ:8208442
当前位置:首页 > 编程开发 > asp教程

如何将实体附加至不同的DataContext

日期:02-11    来源:中国设计秀    作者:cnwebshow.com

注意:u1e中国设计秀
u1e中国设计秀
     1.本文中所提到的“实体”均为由LINQ TO SQL生成的(即.dbml)u1e中国设计秀
u1e中国设计秀
     2.你需要了解LINQ TO SQL对表关联的实现方式,EntitySet 和 EntityRefu1e中国设计秀
u1e中国设计秀
     也许你看到标题后,会觉得问题比较抽象,那么我举个实例来具体说明一下问题。u1e中国设计秀
u1e中国设计秀
u1e中国设计秀
u1e中国设计秀
      在基于LINQ TO SQL的N层架构中,假如我们需要对一个实体进行更新,那么流程应是这样:u1e中国设计秀
u1e中国设计秀
u1e中国设计秀
u1e中国设计秀
流程u1e中国设计秀
u1e中国设计秀
u1e中国设计秀
BLL.GetModel(p=>p.id==1) --> 修改相应属性(字段)值 --> BLL.Update(Entity entity) --> DAL.Update(Entity entity) --> 更新成功u1e中国设计秀
u1e中国设计秀
u1e中国设计秀
u1e中国设计秀
     此时,我们需要将这个实体从业务层(BLL)传递到数据访问层(DAL),当GetModel方法返回实体后会立即释放掉DataContext,然后到了执行DAL.Update(Entity entity)方法时又重新实例化一个DataContext来进行更新操作;可见被传递的实体是从第一个DataContext传递到另一个DataContext,在LINQ TO SQL中这种跨越不同DataContext操作时,需要先进行附加操作,也就是context.Entity.Attach(entity,true); 最后再context.SubmitChanges();u1e中国设计秀
u1e中国设计秀
u1e中国设计秀
u1e中国设计秀
还是看看代码吧:u1e中国设计秀
u1e中国设计秀
u1e中国设计秀
u1e中国设计秀
代码 u1e中国设计秀
class BLLu1e中国设计秀
{u1e中国设计秀
  PRivate readonly DAL dal = new DAL();u1e中国设计秀
  public LinqToSqlProvider.User GetModel(Expression<Func<LinqToSqlProvider.User, bool>> expression)u1e中国设计秀
{u1e中国设计秀
   dal.GetModel(expression);u1e中国设计秀
}u1e中国设计秀
  public void Update(LinqToSqlProvider.User entity)u1e中国设计秀
  {u1e中国设计秀
     dal.Update(entity);u1e中国设计秀
  }u1e中国设计秀
}u1e中国设计秀
u1e中国设计秀
class DALu1e中国设计秀
{u1e中国设计秀
        u1e中国设计秀
        public LinqToSqlProvider.User GetModel(Expression<Func<LinqToSqlProvider.User, bool>> expression)u1e中国设计秀
        {u1e中国设计秀
            LinqToSqlProvider.User entry = new CriTextBroadcast.LinqToSqlProvider.User();u1e中国设计秀
            using (CriTextBroadcastDBDataContext context = DataContext)u1e中国设计秀
            {u1e中国设计秀
                entry =  context.User.SingleOrDefault(expression);u1e中国设计秀
            }u1e中国设计秀
            return entry;u1e中国设计秀
        }u1e中国设计秀
u1e中国设计秀
        public void Update(LinqToSqlProvider.User entity)u1e中国设计秀
        {u1e中国设计秀
           using (CriTextBroadcastDBDataContext context = DataContext)u1e中国设计秀
            {u1e中国设计秀
                context.User.Attach(entry, true);u1e中国设计秀
                context.SubmitChanges();u1e中国设计秀
            }u1e中国设计秀
        }u1e中国设计秀
}u1e中国设计秀
u1e中国设计秀
u1e中国设计秀
实际我们用以上代码操作时,会出现此异常:u1e中国设计秀
u1e中国设计秀
已尝试 Attach 或 Add 实体,该实体不是新实体,可能是从其他 DataContext 中加载来的......u1e中国设计秀
u1e中国设计秀
u1e中国设计秀
u1e中国设计秀
      查了N多资料未果,后来还是在一国外的帖子里看到了类似问题。原来是这个实体对应的表有若干个关联表,如:User -> Message ,User -> Images等,u1e中国设计秀
u1e中国设计秀
在生成实体类时会自动产生:EntitySet<Message> Message这样的属性,由于我们在获取实体时并未将这些关联的内容一起读出来,而在附加时(Attach)这些属性便会出现ObjectDisposedException异常,也就是因为之前查询这个实体时的DataContext已经释放掉了导致的。u1e中国设计秀
u1e中国设计秀
u1e中国设计秀
u1e中国设计秀
解决方法:u1e中国设计秀
u1e中国设计秀
u1e中国设计秀
u1e中国设计秀
代码 u1e中国设计秀
/// <summary>u1e中国设计秀
        /// 辅助LinqToSql实体与原DataContext分离u1e中国设计秀
        /// </summary>u1e中国设计秀
        /// <typeparam name="TEntity"></typeparam>u1e中国设计秀
        /// <param name="entity"></param>u1e中国设计秀
        public static void Detatch<TEntity>(TEntity entity)u1e中国设计秀
        {u1e中国设计秀
u1e中国设计秀
            Type t = entity.GetType();u1e中国设计秀
u1e中国设计秀
            System.Reflection.PropertyInfo[] properties = t.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);u1e中国设计秀
u1e中国设计秀
            foreach (var property in properties)u1e中国设计秀
            {u1e中国设计秀
u1e中国设计秀
                string name = property.Name;u1e中国设计秀
u1e中国设计秀
                if (property.PropertyType.IsGenericType &&u1e中国设计秀
u1e中国设计秀
                property.PropertyType.GetGenericTypeDefinition() == typeof(EntitySet<>))u1e中国设计秀
                {u1e中国设计秀
u1e中国设计秀
                    property.SetValue(entity, null, null);u1e中国设计秀
u1e中国设计秀
                }u1e中国设计秀
u1e中国设计秀
            }u1e中国设计秀
u1e中国设计秀
            System.Reflection.FieldInfo[] fields = t.GetFields(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);u1e中国设计秀
u1e中国设计秀
            foreach (var field in fields)u1e中国设计秀
            {u1e中国设计秀
u1e中国设计秀
                string name = field.Name;u1e中国设计秀
u1e中国设计秀
                if (field.FieldType.IsGenericType &&u1e中国设计秀
u1e中国设计秀
                field.FieldType.GetGenericTypeDefinition() == typeof(EntityRef<>))u1e中国设计秀
                {u1e中国设计秀
u1e中国设计秀
                    field.SetValue(entity, null);u1e中国设计秀
u1e中国设计秀
                }u1e中国设计秀
u1e中国设计秀
            }u1e中国设计秀
u1e中国设计秀
            System.Reflection.EventInfo eventPropertyChanged = t.GetEvent("PropertyChanged");u1e中国设计秀
u1e中国设计秀
            System.Reflection.EventInfo eventPropertyChanging = t.GetEvent("PropertyChanging");u1e中国设计秀
u1e中国设计秀
            if (eventPropertyChanged != null)u1e中国设计秀
            {u1e中国设计秀
u1e中国设计秀
                eventPropertyChanged.RemoveEventHandler(entity, null);u1e中国设计秀
u1e中国设计秀
            }u1e中国设计秀
u1e中国设计秀
            if (eventPropertyChanging != null)u1e中国设计秀
            {u1e中国设计秀
u1e中国设计秀
                eventPropertyChanging.RemoveEventHandler(entity, null);u1e中国设计秀
u1e中国设计秀
            }u1e中国设计秀
u1e中国设计秀
        }u1e中国设计秀
u1e中国设计秀
u1e中国设计秀
应在获得实体后使用Detach(entity)方法将实体与原DataContext分离,然后再附加(Attach)到新的DataContext中去u1e中国设计秀
u1e中国设计秀
 u1e中国设计秀

本文引用地址:/bc/article_46120.html
网站地图 | 关于我们 | 联系我们 | 网站建设 | 广告服务 | 版权声明 | 免责声明