You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用EF Core和内存Sqlite做单元测试时测试运行器出现栈溢出

排查内存Sqlite添加实体时的跨平台栈溢出问题

看起来你遇到了一个挺棘手的场景:在Ubuntu 20.04上用内存Sqlite做单元测试时,向DbContext添加实体直接触发栈溢出,但读取数据完全正常,而且在macOS上运行毫无问题。结合你的代码和描述,我整理了几个优先排查的方向:

1. 先检查BoardGameBuilder的实现逻辑

栈溢出最常见的根源就是无限递归,虽然你怀疑不是循环依赖,但Builder模式很容易出现这类低级错误:

  • 检查Builder的WithXxx方法是否不小心写成了递归调用自身,比如:
    // 错误示例:返回了自身的方法调用,导致无限递归
    public BoardGameBuilder WithName(string name) {
        this.Name = name;
        return WithName(name); 
    }
    
    正确的链式调用写法应该是return this;。
  • 另外检查BoardGame实体类的构造函数、属性setter,有没有递归触发的逻辑(比如某个属性的setter会修改另一个属性,而后者又回调回来修改当前属性)。

2. 排查内存Sqlite的跨平台配置差异

既然问题只在Ubuntu上出现,大概率和Sqlite的运行时行为有关:

  • 检查你的TestDbFactory中内存Sqlite的连接字符串,是否在Ubuntu上缺少必要参数?比如是否添加了Cache=Shared?内存Sqlite在Linux上的默认缓存行为可能和macOS不同,多个DbContext实例共享连接时可能触发异常。
  • 临时将内存Sqlite替换为临时文件Sqlite(比如连接字符串用Data Source=./temp_test.db;Mode=Memory;Cache=Private),如果替换后问题消失,说明是内存Sqlite在Linux上的特定bug,此时可以考虑升级EF Core到最新稳定版,或者改用文件数据库做测试。
  • 确认你使用的EF Core版本在Linux上有没有已知的内存Sqlite相关bug,比如旧版本的EF Core在处理某些实体映射时的递归问题。

3. 检查DbContext和实体的EF Core配置

  • 查看BoardGamesDbContext中是否重写了SaveChanges/SaveChangesAsync方法,里面有没有递归调用逻辑?比如调用SaveChanges时又触发了实体的变更,导致循环调用。
  • 检查BoardGame实体的导航属性配置,如果有双向导航(比如BoardGame关联Category,Category又关联回BoardGame),是否正确配置了EF Core的关系(比如用[InverseProperty]或者Fluent API)?虽然读取数据没问题,但添加实体时EF Core的变更追踪可能会遍历导航属性,在Linux运行时的栈限制下触发溢出。

4. 调试定位具体的调用栈

栈溢出时虽然很难拿到完整的调用栈,但可以尝试以下方法缩小范围:

  • 在Ubuntu上用VS Code或其他调试器单步执行测试,观察添加实体前的最后几步调用,定位到递归的源头。
  • 尝试逐个添加TestBoardGames中的实体,看看是添加第一个就溢出,还是某个特定实体触发问题,这样可以锁定到具体实体的构造或配置问题。

5. 临时排除AutoMapper Mock的影响

虽然读取数据时Mock正常工作,但添加实体时EF Core的追踪逻辑可能间接触发Mapper的某些行为,你可以暂时简化Mock的Setup:

// 暂时替换为固定返回值,排除Mapper的影响
_mapperMock.Setup(mock => mock.Map<BoardGameDto>(It.IsAny<Models.BoardGame>()))
           .Returns(new BoardGameDto(0, "Test", 0, 0, 0));

如果替换后栈溢出消失,说明Mapper的Setup存在隐藏的递归问题。


内容的提问来源于stack exchange,提问作者Łukasz Sypniewski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 14:02:37