1. ホーム
  2. データベース

IEntityChangeTracker の複数のインスタンスからエンティティオブジェクトを参照できない場合の対処法

2022-02-09 19:20:09

EF を使用して、関係が確立しているテーブルに新しいレコードを追加する場合。

1つのエンティティオブジェクトを複数のIEntityChangeTrackerのインスタンスから参照することはできません。 または エンティティオブジェクトは、IEntityChangeTracker の複数のインスタンスから参照できません。

MVC + EF for demosの学習中に遭遇した例外メッセージ。Webでいくつか調べてもよくわからなかったので、しばらく放り投げていました。

まずはエラーコード。

    public class CollegeInfo
    {
        private StudentManageContext stuCtx=new StudentManageContext();
        public Models.CollegeInfoModel GetModel(Guid collegeId)
        {
            var model = stuCtx.CollegeInfoes.SingleOrDefault(s => s.CollegeId == collegeId);

            return model;
        }
           
        public int Add(Models.CollegeInfoModel model)
        {
            stuCtx.CollegeInfoes.Add(model);
            int count = stuCtx.SaveChanges();
            return count;
        }   
      
        public int Update(Models.CollegeInfoModel model)
        {
            Models.CollegeInfoModel oldModel = stuCtx.CollegeInfoes.Find(model.CollegeId);
            oldModel = model;
            stuCtx.Entry(oldModel).State = System.Data.EntityState.Modified;
            return stuCtx.SaveChanges();
        }
    }

    public class DepartmentInfo
    {
        private StudentManageContext stuCtx=new StudentManageContext();
        public Models.DepartmentInfoModel GetModel(Guid departmentId)
        {
            var model = stuCtx.DepartmentInfoes.SingleOrDefault(s => s.DepartmentId == departmentId);

            return model;
        }
       
        public int Add(Models.DepartmentInfoModel model)
        {
            stuCtx.DepartmentInfoes.Add(model);
            int count = stuCtx.SaveChanges();

            return count;
        }
       
        public int Update(Models.DepartmentInfoModel model)
        {
            Models.DepartmentInfoModel oldModel = stuCtx.DepartmentInfoes.Find(model.DepartmentId);
            oldModel = model;
            stuCtx.Entry(oldModel).State = System.Data.EntityState.Modified;
            return stuCtx.SaveChanges();
        }
    }

使用表关系图:


この2つのテーブルは1対多の関係にあり、DepartmentInfoのcollegeInfoIdは外部キーである。

DepartmentInfoのコードを追加します。

        static void Main(string[] args)
        {
            Database.SetInitializer<StudentManageContext>(new DropCreateDatabaseIfModelChanges<StudentManageContext>());

            

CollegeInfoModel collegex = 新しい BLL.CollegeInfo().GetModel()を使用します。 新しい Guid( "B956CA6F-DD7D-4436-9099-484366A5F0B7" ));

            DepartmentInfoModel depart = new DepartmentInfoModel()
            {
                DepartmentId = Guid.NewGuid(),
                DepartmentName = "depart" + DateTime.Now.ToString(),
                CollegeInfoObj = collegex
            };
            new BLL.DepartmentInfo().Add(depart);
         }

この時点では、次のように表示されます。 1 つのエンティティオブジェクトを IEntityChangeTracker の複数のインスタンスで参照することはできません。 または エンティティオブジェクトは、IEntityChangeTracker の複数のインスタンスから参照できません。 の例外です。

その理由は  CollegeInfoModel collegex = 新しい BLL.CollegeInfo().GetModel()を使用します。 新しい Guid( "B956CA6F-DD7D-4436-9099-484366A5F0B7" ));および  新しい BLL.DepartmentInfo().Add(depart)。 この2行のコードは、2つの異なるStudentManageContextオブジェクトを使用することで発生します。エラーコードを詳しく見てみると、どちらのクラスにも プライベート StudentManageContext stuCtx= 新しい StudentManageContext();を使用します。 <スパン もうお分かりでしょうか。要するに、やりたい操作はすべて同じDbContext上で行わなければならないのです。 注:StudentManageContextはDbContextから派生したものです。

解決策1

        static void Main(string[] args)
        {
            Database.SetInitializer<StudentManageContext>(new DropCreateDatabaseIfModelChanges<StudentManageContext>());

            CollegeInfoModel collegex = new BLL.CollegeInfo().GetModel(new Guid("B956CA6F-DD7D-4436-9099-484366A5F0B7"));

            DepartmentInfoModel depart = new DepartmentInfoModel()
            {
                DepartmentId = Guid.NewGuid(),
                DepartmentName = "depart" + DateTime.Now.ToString(),
               
            };
            //new BLL.DepartmentInfo().Add(depart); 将这句代码改成下面两句
            collegex.Departments.Add(depart);
            new BLL.CollegeInfo().Update(collegex);
         }


原因就是:Update时与GetModel用得时同一个DBContext。

解决方案二:

    public class CollegeInfo:BaseModel
    {        
        public Models.CollegeInfoModel GetModel(Guid collegeId)
        {
            var model = stuCtx.CollegeInfoes.SingleOrDefault(s => s.CollegeId == collegeId);

            return model;
        }
           
        public int Add(Models.CollegeInfoModel model)
        {
            stuCtx.CollegeInfoes.Add(model);
            int count = stuCtx.SaveChanges();
            return count;
        }   
      
        public int Update(Models.CollegeInfoModel model)
        {
            Models.CollegeInfoModel oldModel = stuCtx.CollegeInfoes.Find(model.CollegeId);
            oldModel = model;
            stuCtx.Entry(oldModel).State = System.Data.EntityState.Modified;
            return stuCtx.SaveChanges();
        }
    }    
    public class DepartmentInfo:BaseModel
    {
       
        public Models.DepartmentInfoModel GetModel(Guid departmentId)
        {
            var model = stuCtx.DepartmentInfoes.SingleOrDefault(s => s.DepartmentId == departmentId);

            return model;
        }
       
        public int Add(Models.DepartmentInfoModel model)
        {
            stuCtx.DepartmentInfoes.Add(model);
            int count = stuCtx.SaveChanges();

            return count;
        }
       
        public int Update(Models.DepartmentInfoModel model)
        {
            Models.DepartmentInfoModel oldModel = stuCtx.DepartmentInfoes.Find(model.DepartmentId);
            oldModel = model;
            stuCtx.Entry(oldModel).State = System.Data.EntityState.Modified;
            return stuCtx.SaveChanges();
        }
    }
    public abstract class BaseModel
    {
        protected StudentManageContext stuCtx = null;
        public BaseModel()
        {
            stuCtx = DataCache.GetCache("StudentManageContext") as StudentManageContext;
            if (stuCtx == null)
            {
                stuCtx = new StudentManageContext();
                DataCache.SetCache("StudentManageContext", stuCtx);
            }
        }
    }

これにより、CollegeInfoとDepartmentInfoが同じDBContextを共有することができるようになる。

取得元:https://www.cnblogs.com/guolihao/p/3213723.html