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

使用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方法中打印参数值:
    public void SaveLastCall(string lastCall)
    {
        Console.WriteLine("待插入值:" + (lastCall ?? "NULL"));
        var sql = "insert into RequestLog (LastCall) values (@LastCall)";
        _db.SaveData(sql, new { LastCall = lastCall }, _connectionString);        
    }
    
    若值为NULL,检查调用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 15:15:58