ASP.NET MVC OnModelCreating抛System.StackOverflowException致运行异常
ASP.NET MVC项目OnModelCreating触发StackOverflowException排查方案
问题复现场景
- 开发环境为Visual Studio 2019
- 异常触发节点为数据库上下文执行
OnModelCreating方法的阶段 - 抛出异常类型为
System.StackOverflowException - 问题特征:
- 异常曾以偶发形式出现,搁置项目一段时间后重启可自行恢复
- 当前异常持续触发,项目完全无法正常启动、无法完成数据库上下文的构建流程
- 数据接入方式:对接规模较大的生产数据库,通过「Code First From Database」反向生成Code First模式的实体模型与数据库上下文
- 对应报错的堆栈截图已随问题描述附带
核心触发根因
这类在大库反向生成场景下出现的栈溢出,几乎都和无终止的递归调用直接相关:
- 实体导航属性形成双向循环引用:反向生成的实体配置中,两个互相依赖的实体配置在遍历映射规则时形成无限递归,不停压入栈帧直到系统分配的栈空间被完全占满
- 自定义配置逻辑触发递归回路:重写
OnModelCreating时追加的全局过滤器、动态配置加载逻辑,内部又反向触发模型构建流程,形成无限嵌套调用 - 旧版EF工具的已知缺陷:VS2019内置的旧版EF反向生成工具,在处理包含上百个实体的大规模库模型时,模型树遍历逻辑存在栈溢出bug,碰到带实体继承、复杂嵌套值类型的场景时,触发栈溢出的概率会显著升高
分步排查与修复操作
- 缩小问题定位范围
临时清空重写的
OnModelCreating方法,仅保留base.OnModelCreating(modelBuilder)基础调用后重启项目。如果异常消失,说明问题来自自行追加的自定义配置逻辑;如果异常仍存在,说明问题出在反向生成的实体映射代码本身。 - 定位循环引用实体对
逐段注释反向生成的实体映射配置代码,从核心业务表配置开始逐个放开,找到触发无限递归的实体对。对循环路径上的导航属性,在配置类中调用Ignore()方法移除映射关系,或是加上[NotMapped]标记避免被纳入模型构建流程。 - 替换老旧的EF工具链
把项目中依赖的EF框架升级到兼容VS2019的最新稳定版本,替换VS2019内置的旧版反向生成工具,重新从数据库生成Code First上下文与实体代码,规避旧版本工具在遍历大模型时的逻辑缺陷。 - 调整模型构建的递归阈值
针对EF6版本的项目,在对应配置节点调整模型构建时的栈深度相关参数,降低嵌套实体树遍历时的栈溢出触发概率。
内容的提问来源于stack exchange,提问作者Hossein Bohlouli
相关产品推荐
相关产品推荐

