AutoFac请求范围不是整个请求

时间:2018-09-21 07:23:48

标签: c# entity-framework autofac dbcontext

我刚刚在我的MVC项目中设置了AutoFac,并将EF DbContext设置为InstancePerRequest。到目前为止,DbContext一直是静态单例。似乎AutoFac的“请求”范围实际上并不是整个请求。我收到错误消息:

  

由于已处理DbContext,因此无法完成操作。

很像some other个问题。

我希望在处理完整个请求之后处理上下文,但是当我尝试访问视图或return语句中的延迟加载属性时,会出现异常。

问题的一个示例:

[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);
}

我最喜欢的解决方案是,如果我可以简单地扩展上下文的范围,使其在整个请求中都持续(singleton并不可行)。否则,我将不得不在整个代码中进行更改,以确保在控制器动作return之前已加载所有内容。

1 个答案:

答案 0 :(得分:0)

我对AutoFac完全不对。这里代码中的问题不是查询的执行被推迟,而是lockItemIds对象是被推迟执行的IEnumerable对象。我加载了列表,并使用旧的上下文将其存储在静态变量中,却没有意识到它没有立即执行。

AutoFac的请求范围很完美。

教训是:使用调试器确保您确切地知道引起问题的对象并检查静态变量。