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.
AddDbContext<XXX>
and configure just the connection string is enough, don't try to modify the service lifetime which isScoped
by default (and should always be so). You must have a problem somewhere else, I'm pretty sure about that. So now you don't even know where it could be, we may be all stuck with this. – BantDbContext
somehow is still being used after the request processing ended, it could be a caching issue, some issue with background threading/task ... The general principle is simple but to pinpoint the exact code that causes the issue, you will have to do that yourself, I don't think someone here can help. – BantSaveChanges
is called as a unit-of-work operation which means after you've done everything with the DbContext that should be all succeeded or failed together, you useSaveChanges
to persist the data changes. – Bant