"操作无法完成,因为DbContext已被处理"异常并且禁用了延迟加载

P.B*_*key 3 c# asp.net-mvc-3 entity-framework-5

鉴于:

    public ActionResult List()
    {
        using (var unitOfWork = new UnitOfWork())
        {
            var result = unitOfWork.Repository.Find<EntityAddress>(a => a.PostalCode == "80001");
            //return View(result.ToList());//NO Exception raised with ToList()
            return View(result);//EXCEPTION RAISED IN VIEW DURING ITERATION
        }            
    }
Run Code Online (Sandbox Code Playgroud)

UnitOfWork是一次性的,处理我的DbContext.它还禁用构造函数中的延迟加载:

    public UnitOfWork()
    {
        _dbContext.Configuration.LazyLoadingEnabled = false;
        Repository = new GenericRepository<MyEntities>(_dbContext);            
    }

    public void Dispose()
    {
        Repository.Dispose();
    }
Run Code Online (Sandbox Code Playgroud)

Find<EntityAddress>()实施工程以:

_dbContext.Set<EntityAddress>().Where(predicate) 其中谓词是类型的参数 Expression<Func<EntityAddress, bool>>

为什么即使在禁用延迟加载后也会出现处理异常?

Ada*_*ras 7

懒惰和急切加载与何时加载查询相关的实体(例如导航属性和集合)有关,而不是在加载查询本身的内容时.

IQuerable<EntityAddress>从返回仓库,无论你是否有延迟加载启用,将直到它列举了在服务器上没有运行查询(不管是通过获取一个枚举foreach循环中,调用Enumerable.ToList<TSource>它,或者将它传递到调用Controller.View下游渲染).

在这种情况下获得异常的原因是因为Controller.View不立即呈现视图(因此不会立即枚举查询).它所做的只是构建一个实例,ViewResult它保存在模型参数(您的查询对象)上,直到MVC在您处理完您的上下文后再渲染视图.

如果要将查询结果传递给视图,则有两个选项:

  1. 将数据库上下文的生命周期延长到控制器的生命周期
  2. 调用Enumerable.ToList<EntityAddress>IQuerable<EntityAddress>数据库上下文被设置之前,并使用所产生的List<EntityAddress>代替IQuerable<EntityAddress>.