文章出處

之前發表過一篇文章題為《關于Entity Framework中的Attached報錯的完美解決方案》,那篇文章確實能解決單個實體在進行更新、刪除時Attached的報錯,注意我這里說的單個實體,指的是要更新或刪除的實體不包含其它實體(比如導航屬性就包含其它實體),也就是簡單POCO對象;但如果不是呢?那么那篇文章里的方法在一定程度上不起作用了,仍會報錯,我開始也想不明白,明明通過IsAttached函數判斷要更新的實體并未Attached,但進行Attaching時但仍然報錯說有相同Key,開始還以為是MS的BUG,后經過多次反復調試發現,報錯是對的,因為他報的錯并不是我當前要更新的實體,而是該實體中關聯的實體,代碼與演示報錯如下:(僅是演示代碼)

public class A
{
   public string a{get;set;}
   public string b{get;set;}
   public string c{get;set;}
   public virtual B b{get;set;}
}

public class B
{
   public string x{get;set;}
   public string y{get;set;}
   public string z{get;set;}
}

var a1= dbContext.Set<A>().Single();
a1.a="test1";
dbContext.SaveChanges();

dbContext.Detach(a1);//從緩存中移除a1實體;


var a2= dbContext.Set<A>().AsNoTracking().Single();
a2.a="test2";
 dbContext.Set<A>().Attach(a2); //報錯,說B相同的KEY已經有Attached
dbContext.Entry(entity).State = EntityState.Modified;
dbContext.SaveChanges(); 

針對這個報錯,我在想,為何查詢實體A的時候能同時關聯查詢實體B并都同時Attached到內存中,而當我執行Detach實體A時,卻沒能關聯Detach實體B,問題根源就在這里,知道這個原因了,現在就是要解決這個問題,如何解決呢?既然知道是Detach實體不全面造成的,那么我只需要獲取到當前DbContext上下文對象中現有的所有已Attached實體,在執行完相應的CRUD時,再全部依次Detach掉即可,解決方案代碼如下:

        /// <summary>
        /// 清空DB上下文中所有緩存的實體對象
        /// </summary>
        private void DetachedAllEntities()
        {
            var objectContext = ((IObjectContextAdapter)this.baseContext).ObjectContext;
            List<ObjectStateEntry> entries = new List<ObjectStateEntry>();
            var states = new[] { EntityState.Added, EntityState.Deleted, EntityState.Modified, EntityState.Unchanged };
            foreach (var state in states)
            {
                entries.AddRange(objectContext.ObjectStateManager.GetObjectStateEntries(state));
            }

            foreach (var item in entries)
            {
                objectContext.Detach(item.Entity);
            }
        }


        public void Commit()  //封裝的統一提交方法
        {
            this.baseContext.SaveChanges();
            this.DetachedAllEntities();//執行清除
        }

在使用的時候配合之前那篇文章的IsAttached函數就能完美解決所有的Attached報錯問題了!


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()