Search code examples
c#databaseentity-frameworkasp.net-coredependency-injection

Cannot access a disposed context instance EF core


I am developing a CRM by .net core mvc and EF which needs a lot of DB connection to retrieve and update information. From time to time I face this error during debugging, this is a big project with a lot of users I don't know how it will work in real usage!

Cannot access a disposed context instance. A common cause of this error is disposing a context instance that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling 'Dispose' on the context instance, or wrapping it in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances.\r\nObject name: 'XXX'.

before I used this setting in startup.cs:

services.AddDbContext<XXX>
                (option => 
                option.UseSqlServer(Configuration.GetConnectionString("YYY"))
                .ServiceLifetime.Singleton);

that setting was lead to another error occasionally:

System.InvalidOperationException: The instance of entity type 'TblZZZ' cannot be tracked because another instance with the same key value for {'ZZZId'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached.

so I have changed my setting to:

services.AddDbContext<XXX>
                (option => 
                option.UseSqlServer(Configuration.GetConnectionString("YYY"))
                .UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking));

now I am facing the Cannot access a disposed context instance. I don't know what setting can solve my issue.

I m using net5.0

Update: my partial class:

public partial class TblXXX
    {
        private ZZZ context;//context
        public TblXXX(ZZZ _context)
        {
            context = _context;
        }
        public TblXXX() { }
//function for check username
   public bool CheckUsernameExit(string username) {
            var u = context.TblXXX
                .Where(e => e.Username == username)
                .FirstOrDefault();
            return (u != null);
        }
}

in my controller:

  public IActionResult Check(UserModelView user)
        {
            if (ModelState.IsValid)
            {
                var r = _viewModel.tblXXX.CheckUsernameExit(user.tblXXX.Username);
                if (r)
                {
                    toastNotification.AddErrorToastMessage("This email is in use. Enter differernt email.");
                 
                    return View("Create", _viewModel);
                }
            

and this is my ViewModel:

 public class UserModelView
    {
        public TblXXX tblXXX { get; set; }
        public List<TblXXX > tblXXXList { get; set; }
    }
          

this is one of the cases I face the error.


Solution

  • In asp.net core the DbContext should be a Scoped service, not a Singleton.

    Change this:

    services.AddDbContext<XXX>
                    (option => 
                    option.UseSqlServer(Configuration.GetConnectionString("YYY"))
                    .ServiceLifetime.Singleton);
    

    To

    services.AddDbContext<XXX>
                    (option => 
                    option.UseSqlServer(Configuration.GetConnectionString("YYY")));