使用Dapper写入SQLite数据库失败排查求助
SQLite插入无报错但无数据写入的排查方案
核心排查方向及解决方法
1. 数据库文件路径不匹配(最可能)
SQLite是文件型数据库,即使读取正常,若用相对路径作为连接字符串,程序运行时的当前工作目录可能和你预期的不一致,导致写入的是另一个隐蔽位置的数据库文件,而你查看的是原文件。
- 验证方式:在
SaveData方法中添加代码,输出当前连接的实际文件路径:
对比输出路径和你手动查看的数据库文件路径,若不一致,把连接字符串改成绝对路径即可。public void SaveData<T>(string sqlStatement, T parameters, string connectionString) { using IDbConnection connection = new SQLiteConnection(connectionString); var sqliteConn = connection as SQLiteConnection; if(sqliteConn != null) { Console.WriteLine($"当前操作的数据库文件:{sqliteConn.DataSource}"); } connection.Execute(sqlStatement, parameters); }
2. 事务未提交导致数据暂存
虽然Dapper默认自动提交,但如果连接被其他操作开启过未提交的事务,插入操作会被挂起,不会写入磁盘。
- 解决方式:显式控制事务,确保提交:
public void SaveData<T>(string sqlStatement, T parameters, string connectionString) { using IDbConnection connection = new SQLiteConnection(connectionString); connection.Open(); using var transaction = connection.BeginTransaction(); try { connection.Execute(sqlStatement, parameters, transaction: transaction); transaction.Commit(); } catch(Exception ex) { transaction.Rollback(); throw new Exception("插入数据失败", ex); } }
3. 参数问题导致插入无效
如果传入的lastCall是null,SQLite会插入NULL值,你可能误以为没写入;或者参数类型与字段类型不兼容(比如字段是TEXT但传入非字符串类型)。
- 验证方式:在
SaveLastCall方法中打印参数值:
若值为NULL,检查调用public void SaveLastCall(string lastCall) { Console.WriteLine("待插入值:" + (lastCall ?? "NULL")); var sql = "insert into RequestLog (LastCall) values (@LastCall)"; _db.SaveData(sql, new { LastCall = lastCall }, _connectionString); }SaveLastCall时传入的参数是否正确。
4. 权限不足导致静默失败
程序运行用户没有数据库文件所在目录的写入权限时,SQLite会静默失败,不会抛出异常。
- 解决方式:将数据库文件移动到有写入权限的目录(比如用户文档目录),或者给当前目录添加写入权限。
5. 验证SQL执行结果
Dapper的Execute方法会返回受影响的行数,通过这个值可以直接判断是否插入成功:
// 修改SaveData方法返回受影响行数 public int SaveData<T>(string sqlStatement, T parameters, string connectionString) { using IDbConnection connection = new SQLiteConnection(connectionString); return connection.Execute(sqlStatement, parameters); } // 调用时打印结果 public void SaveLastCall(string lastCall) { var sql = "insert into RequestLog (LastCall) values (@LastCall)"; int rows = _db.SaveData(sql, new { LastCall = lastCall }, _connectionString); Console.WriteLine($"插入受影响行数:{rows}"); }
- 若返回
1:说明插入成功,问题出在你查看的数据库文件不对(回到第1点排查)。 - 若返回
0:说明SQL语句或参数有问题,检查表名、字段名拼写是否正确,参数是否匹配。
补充说明
从你的数据库结构来看,RequestLog表包含Id(自增主键)和LastCall(TEXT类型)字段,你的插入SQL语句是正确的,排除语法问题。
内容的提问来源于stack exchange,提问作者GasPanic
相关产品推荐
相关产品推荐

