0

I just set up AutoFac in my MVC project and set my EF DbContext to InstancePerRequest. Until now DbContext has been a static singleton. It seems that AutoFac's "request" scope is not really the entire request. I'm getting the error message:

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

Much like some other questions.

I would expect the context to be disposed after the entire request has been handled, but the exception is showing up when I try to access lazily loaded properties in views or return statements.

An example of the problem:

[HttpGet]
public JsonResult GetLotoLockNumbers(int permitId)
{
    var lockNums = lockService.FindLotoLockNumbers(permitId);

    // this line throws an exception because... (go to last line)
    return Json(string.Join(", ", lockNums), JsonRequestBehavior.AllowGet); 
}

public IEnumerable<string> FindLotoLockNumbers(int permitId)
{
    // returns an attached entity
    var permit = Repository.GetDBEntityWithId<PermPermit>(permitId);
    return GetLotoLockNumsForPermit(permit).AsEnumerable();
}

private IEnumerable<string> GetLotoLockNumsForPermit(PermPermit permit, int? configLockItemId = null)
{
    // lazily accesses virtual properties
    var lotoLockItems = permit.permitSections.SelectMany(section => section.childs.Where(
        (sectionItem) => IsLotoLockSectionItem(sectionItem, configLockItemId))).AsEnumerable();
    return lotoLockItems.SelectMany(item => LotoLockHelper.ParseLockNums(item.value)).AsEnumerable();
}

private bool IsLotoLockSectionItem(PermPermitSectionItem item, int? configLockItemId = null)
{
    // ...the context has been exposed when this line gets lazily executed
    return lockItemIds.Contains(item.confSectionItem.id);
}

My favourite solution would be if I could simply extend the scope of the context so that it lasts for the whole request (a singleton is not ok). Otherwise, I'll have to make changes throughout the code to make sure that everything is loaded before controller actions return.

MyiEye
  • 445
  • 1
  • 4
  • 14

1 Answers1

0

I was all wrong about AutoFac. The problem in the code here is not that the query's execution is deferred, it's that the lockItemIds object is an IEnumerable who's execution gets deferred. I loaded the list and stored it in a static variable using an old context and didn't realize that it wasn't executed immediately.

AutoFac's request scope is perfect.

The lesson is: use the debugger to make sure you know exactly which object is causing the problem and check your static variables.

MyiEye
  • 445
  • 1
  • 4
  • 14