简体   繁体   中英

operation cannot be completed because the DbContext has been disposed."

While running the project am getting this error "The operation cannot be completed because the DbContext has been disposed".While checking the net I have seen many answers for this but I think I have that all in my code.Please verify my code and let me know what's wrong in it ,Please help me... This the code written in the controller and in the Elmah am getting the error.

 public ActionResult Create(Permissions permissions)
    {
        try
        {
            using (var db = new AdminDb())
            {
                //delete existing permissions of the selected role..
                IList<int> ModuleMenu = (from d in db.MenuConfig.AsNoTracking()
                                         where d.ModuleId == permissions.ModuleId
                                         select d.MenuConfigId).ToList();

                var RoleMenu = (from c in db.RoleMenuMapping where ModuleMenu.Contains((int)c.MenuId) && c.RoleId == permissions.RoleId select c).ToList();

                foreach (var rm in RoleMenu)
                {
                    db.RoleMenuMapping.Remove(rm);
                    db.SaveChanges(); // Added for avoiding The object is in a detached state Error
                }

                // add new permissions to db
                if (permissions.RoleMenu != null)
                {
                    foreach (var rm in permissions.RoleMenu)
                    {
                        RoleMenuMapping RoleMapping = new RoleMenuMapping();
                        //to get the next ID
                        string EntityName = (db as IObjectContextAdapter).ObjectContext.CreateObjectSet<RoleMenuMapping>().EntitySet.Name;
                        Int32 nextval = new Assyst.PanERP.Common.Common().getNextSequence(EntityName);
                        RoleMapping.RoleMenuMappingId = nextval;
                        RoleMapping.RoleId = permissions.RoleId;
                        RoleMapping.MenuId = rm.Id;
                        RoleMapping.BusinessUnitId = 1;
                        RoleMapping.MenuAdd = (rm.Add == true ? 1 : 0);
                        RoleMapping.MenuDelete = (rm.Delete == true ? 1 : 0);
                        RoleMapping.MenuModify = (rm.Modify == true ? 1 : 0);
                        RoleMapping.MenuView = (rm.View == true ? 1 : 0);
                        RoleMapping.MenuImport = (rm.Import == true ? 1 : 0);
                        RoleMapping.MenuExport = (rm.Export == true ? 1 : 0);
                        RoleMapping.MenuRestrictedView = (rm.RestrictedView == true ? 1 : 0);
                        RoleMapping.MenuBulkUpdate = (rm.BulkUpdate == true ? 1 : 0);
                        RoleMapping.MenuBulkDelete = (rm.BulkDelete == true ? 1 : 0);
                        RoleMapping.MenuSpecial1 = (rm.Special1 == true ? 1 : 0);
                        RoleMapping.MenuSpecial2 = (rm.Special2 == true ? 1 : 0);
                        RoleMapping.MenuSpecial3 = (rm.Special3 == true ? 1 : 0);
                        RoleMapping.MenuSpecial4 = (rm.Special4 == true ? 1 : 0);
                        RoleMapping.MenuSpecial5 = (rm.Special5 == true ? 1 : 0);

                        db.RoleMenuMapping.Add(RoleMapping);
                    }
                }

                db.SaveChanges();

                ViewBag.RoleId = new SelectList(db.Role, "Id", "Code");
                ViewBag.Module = new SelectList(db.Module, "ModuleId", "ModuleName");
                ViewBag.ScreenType = new[] { new SelectListItem { Text = "Select", Value = "select" }, new SelectListItem { Text = "Master", Value = "1" }, new SelectListItem { Text = "Report", Value = "2" }, new SelectListItem { Text = "Transaction", Value = "3" } };

                return View("Index");
            }
        }
        catch (Exception ex)
        {
            Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
            return Json(new { Result = "ERROR", Message = ex.Message });
        }
    }

I think the problem is in those 2 lines

ViewBag.RoleId = new SelectList(db.Role, "Id", "Code");
ViewBag.Module = new SelectList(db.Module, "ModuleId", "ModuleName");

You are passing DbSet s as IEnumerable to the SelectList constructor. If the constructor does not iterate the passed enumerable and just store it, then the DbContext goes out of scope and is disposed (due to using (var db = ... ), and the ObjectDisposedException will be thrown anytime the DbSet enumerable is iterated.

I think you should make sure everything you use from the db context is materialized before disposing the context. For instance, adding ToList() or Select(...).ToList() like this

ViewBag.RoleId = new SelectList(db.Role.ToList(), "Id", "Code");
ViewBag.Module = new SelectList(db.Module.ToList(), "ModuleId", "ModuleName");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM