[Entity Framework] 錯誤處理: 一個實體物件不能被多個 IEntityChangeTracker 的執行個體參考

錯誤處理: 一個實體物件不能被多個 IEntityChangeTracker 的執行個體參考

問題簡述

 

筆者有一組使用者(User)與角色(Role)的資料表結構如下,Role Table中已存在數筆預設角色資料;筆者想做的事情很簡單,就是建立一個新的使用者,並且賦予所有角色權限給他。

 

image

 

程式碼如下

{
    private TestEntities db = new TestEntities();


    // 取得所有角色清單
    public ICollection<Role> GetRoles()
    {
        TestEntities entities = new TestEntities();
        return entities.Roles.ToList();
    }

    // 建立使用者 [測試]
    public ActionResult CreateUser()
    {
        // prepare user instance
        User user = new User()
        {
            Email = "Chris@Xxx.com",
            IsEnable = true,
            Name = "Chris Chen",
            Password = "ooxx",
            RegisterOn = DateTime.Now,
            UserId = "wasichris",
            Roles = GetRoles()
        };

        // save user
        db.Users.Add(user);
        db.SaveChanges();
        return RedirectToAction("Index");
    }
}

 

直接給他執行下去,就直接給我報錯回來

訊息寫著"一個實體物件不能被多個 IEntityChangeTracker 的執行個體參考"

An entity object cannot be referenced by multiple instances of IEntityChangeTracker

 

image

 

 

問題探討

 

搜尋一下前人的智慧後發現,Entity Framework會使用 IEntityChangeTracker 的執行個體,追蹤對已附加至 ObjectContext 的物件所做之變更。每個被追蹤的物件都有一個 IEntityChangeTracker 的執行個體。簡單來說,該錯誤訊息就明確指出相同一個物件實體(user)是不能被多個 IEntityChangeTracker 的執行個體(db 及 entities)參考,因此才會在user加入db的追蹤時報出錯誤來。

 

image

 

 

解決方式

 

使用相同的DbContext 執行個體即可。

 

image

    {
        private TestEntities db = new TestEntities();

        // 取得所有角色清單
        public ICollection<Role> GetRoles()
        {
            //TestEntities entities = new TestEntities();
            //return entities.Roles.ToList();

            // 使用相同的DbContext 執行個體
            return db.Roles.ToList();
        }

        // 建立使用者 [測試]
        public ActionResult CreateUser()
        {
            // prepare user instance
            User user = new User()
            {
                Email = "Chris@Xxx.com",
                IsEnable = true,
                Name = "Chris Chen",
                Password = "ooxx",
                RegisterOn = DateTime.Now,
                UserId = "wasichris",
                Roles = GetRoles()
            };

            // save user
            db.Users.Add(user);
            db.SaveChanges();
            return RedirectToAction("Index");
        }
    }

 

執行後順利寫入資料庫

 

image

 

 

參考資訊

 

http://stackoverflow.com/questions/10191734/entity-object-cannot-be-referenced-by-multiple-instances-of-ientitychangetracker

http://msdn.microsoft.com/zh-tw/library/bb738695%28v=vs.90%29.aspx


希望此篇文章可以幫助到需要的人

若內容有誤或有其他建議請不吝留言給筆者喔 !