使用MS Tests+SQLite内存库测试Dapper API时提示表不存在
问题诊断与解决方案
核心原因分析
SQLite内存数据库的连接特性是每个新连接对应独立的内存实例,如果测试中创建连接并填充数据后,控制器通过IDbConnectionFactory获取了新连接,这个新连接内并未创建过表和数据,自然会报表不存在。
具体修复步骤
1. 复用同一个SQLite连接实例
SQLite内存库的生命周期与连接绑定,需让IDbConnectionFactory始终返回已初始化的同一连接:
// 初始化SQLite连接并保持打开 var sqliteConn = new SqliteConnection("Data Source=:memory:"); sqliteConn.Open(); // 执行建表与数据填充脚本 sqliteConn.Execute("CREATE TABLE tbl03_holiday (id INT, holiday_date DATE, holiday_name TEXT)"); sqliteConn.Execute("INSERT INTO tbl03_holiday VALUES (1, '2024-01-01', 'New Year')"); // 注册自定义连接工厂,返回同一实例 services.AddSingleton<IDbConnectionFactory>(_ => new InMemoryConnFactory(sqliteConn)); // 自定义连接工厂实现 public class InMemoryConnFactory : IDbConnectionFactory { private readonly IDbConnection _conn; public InMemoryConnFactory(IDbConnection conn) => _conn = conn; public IDbConnection CreateConnection() => _conn; }
2. 统一表名大小写与引号规则
PostgreSQL默认区分表名大小写(带双引号时),而SQLite默认不区分。如果生产代码中查询用了带引号的表名(如"tbl03_holiday"),需确保测试建表语句与查询语句的写法完全一致,避免因标识符规则差异导致表找不到。
3. 确保连接始终处于打开状态
SQLite内存数据库会在连接关闭时立即销毁所有数据,测试全程需保持连接打开,切勿提前关闭。
4. 确认DI注册优先级
确保测试中注册的IDbConnectionFactory覆盖了生产环境的注册逻辑,避免控制器意外获取到PostgreSQL的连接工厂实例。
快速验证方法
在控制器处理请求前,通过同一连接执行查询验证表存在:
// 测试中注入控制器后,先验证数据 var dataCount = sqliteConn.QueryFirst<int>("SELECT COUNT(*) FROM tbl03_holiday"); Console.WriteLine($"当前表数据量:{dataCount}");
内容的提问来源于stack exchange,提问作者Jack Hurley
相关产品推荐
相关产品推荐

