Repository模式中,Update总是失败及其解析

在更新或删除model的时候,出现错误:

ASP.NET MVC - Attaching an entity of type 'MODELNAME' failed because another entity of the same type already has the same primary key value

   /// <summary>
        /// 更新对象
        /// </summary>
        /// <param name="model">实体</param>
        /// /// <returns></returns>
        public virtual bool Update(T model)
        {
            this.DbContext.Entry<T>(model).State = EntityState.Detached;
            this.DbContext.Set<T>().Attach(model);
            this.DbContext.Entry<T>(model).State = EntityState.Modified;
            return this.DbContext.SaveChanges() > 0;
        }

 /// <summary>
        /// 删除对象
        /// </summary>
        /// <param name="model">实体</param>
        public virtual bool Delete(T model)
        {
            this.DbContext.Set<T>().Remove(model);
            return this.DbContext.SaveChanges() > 0;
        }
原因:在Context中还保留有当前实体的副本所致,这里只要我们将实体副本从内存中完全移除,就可以了。

解决方式:

定义一个方法:用于监测Context中的Entity是否存在,如果存在,将其Detach,防止出现问题。

 //用于监测Context中的Entity是否存在,如果存在,将其Detach,防止出现问题。
        private Boolean RemoveHoldingEntityInContext(T entity)
        {
            var objContext = ((IObjectContextAdapter)_context).ObjectContext;
            var objSet = objContext.CreateObjectSet<T>();
            var entityKey = objContext.CreateEntityKey(objSet.EntitySet.Name, entity);

            Object foundEntity;
            var exists = objContext.TryGetObjectByKey(entityKey, out foundEntity);
          
            if (exists)
            {
                objContext.Detach(foundEntity);
            }

            return (exists);
        }

然后在update 或delete之前调用:

 public T Remove(T entity)
        {
            try
            {
                RemoveHoldingEntityInContext(entity);

                _context.DbSet<T>().Attach(entity);
                return _context.DbSet<T>().Remove(entity);
            }
            catch (DbEntityValidationException dbex)
            {
                var msg = string.Empty;
                foreach (var validationErrors in dbex.EntityValidationErrors)
                    foreach (var validateionError in validationErrors.ValidationErrors)
                        msg += string.Format("属性:{0} 错误:{1}", validateionError.PropertyName, validateionError.ErrorMessage);
                var fail = new Exception(msg, dbex);
                throw fail;
            }
        }

        public T Update(T entity)
        {
            try
            {
                RemoveHoldingEntityInContext(entity);

                var updated = _context.DbSet<T>().Attach(entity);
                _context.DbContext.Entry(entity).State = EntityState.Modified;
                return updated;
            }
            catch (DbEntityValidationException dbex)
            {
                var msg = string.Empty;
                foreach (var validationErrors in dbex.EntityValidationErrors)
                    foreach (var validateionError in validationErrors.ValidationErrors)
                        msg += string.Format("属性:{0} 错误:{1}", validateionError.PropertyName, validateionError.ErrorMessage);
                var fail = new Exception(msg, dbex);
                throw fail;
            }
        }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值