zoukankan      html  css  js  c++  java
  • An entity object cannot be referenced by multiple instances of IEntityChangeTracker 的解决方案

    使用EF对建立了关系的表新增记录时出现:

    An entity object cannot be referenced by multiple instances of IEntityChangeTracker一个实体对象不能由多个 IEntityChangeTracker 实例引用

    在学习MVC+EF做demo时碰到的一个异常信息。在网上查了些,看得不是很明白,就自己折腾了一会儿。

    先上出错的代码:

        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();
            }
        }
    使用表关系图:
    image

    两个表是一对多的关系。DepartmentInfo 中的collegeInfoId是外键。

    添加DepartmentInfo代码:

            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(),
                    CollegeInfoObj = collegex
                };
                new BLL.DepartmentInfo().Add(depart);
             }

    这时会出现An entity object cannot be referenced by multiple instances of IEntityChangeTracker一个实体对象不能由多个 IEntityChangeTracker 实例引用的异常

    原因是  CollegeInfoModel collegex = new BLL.CollegeInfo().GetModel(new Guid("B956CA6F-DD7D-4436-9099-484366A5F0B7"));  和  new BLL.DepartmentInfo().Add(depart); 这两句代码使用的是两个不同的StudentManageContext 对象造成的,可以仔细看看出错代码,两个类都有 private StudentManageContext stuCtx=new StudentManageContext(); ,到这儿你是否明白了呢。简单的来说,你要做的操作都必须在同一DbContext上完成。注:StudentManageContext派生于DbContext.

    解决方案一:

            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。

  • 相关阅读:
    Eclipse+Pydev +Django搭建开发环境时容易出错的几点
    小白对于数据库的初步理解
    个人PC搭建自己的虚拟服务器
    xss 学习(一)
    python爬虫学习(一)
    php常用函数
    sqlmap基础命令
    metinfo 5.3.19 管理员密码重置
    nmap常用命令
    Web安全开发手册
  • 原文地址:https://www.cnblogs.com/guolihao/p/3213723.html
Copyright © 2011-2022 走看看