前言
使用了ASP.NET MVC Framework Entity AutoFac 的 项目,最近发现不同的HTTP请求Controller-Action 的时候,出现了错误,The context cannot be used while the model is being created , 大概的意思就是出现了线程共享安全的问题,在entity 返回IQueryable 转化成ToList 对象的时候抛出这个错误。
起初以为是使用了entity 数据库关系对象,主键和外键引用出现了问题,经过反复测试,发现不是这个问题,然后又考虑是不是使用了IOC单个例程SingleInstance() 的问题, 然后修改成生命周期注入InstancePerLifetimeScope(), 还是不能解决问题。最后仔细观察发现,原来是BLL和接口使用了IOC注入,DAL也使用了IOC注入, 但是 Entity 基类接口和 DAL数据库访问接口使用了静态单个例程的上下文,当然是用这种方式是正确的,但是恰好这里就出现了单例程共享访问冲突。
正常情况:一个HTTP请求访问在后台处理过程如下:
Client(浏览器)->HTTPRequest -> MVCController (IOC注入BLL)-> BLL (IOC注入DAL)->DAL(访问Entity基类)
看出来问题了吧? Entity 建议对于单个用户建议使用相同的上下文例程,但是不同的HTTP请求不同又用户不能共享例程。
解决方案:

上面是通过静态对象共享一个上下文的方式,这种方式不能通过IOC注入。

如上图,修改为通过 注入DbContextFactory 类和接口的方式IOC注入。

BLL和DAL的注入依旧使用单例程。

然后在BaseDal Entity 基类中对 DbContext 对象进行注入。

完整的项目结构如上图, 最终数据绑定的页面:这个页面有两个Ajax 请求 Action返回数据,不会报异常。

本文介绍了一个使用ASP.NET MVC项目的线程安全问题,具体表现为在HTTP请求处理过程中出现错误“The context cannot be used while the model is being created”。文章详细分析了问题原因,并提供了一种解决方案:通过注入DbContextFactory类和接口的方式替换静态上下文对象,从而避免线程冲突。

被折叠的 条评论
为什么被折叠?



