用 System.Data.SQLite 读取本地。db 文件需安装完整版 NuGet 包,连接字符串用绝对路径如 ”Data Source=C:ppdata.db;Version=3;”,注意大小写敏感、保留字加引号、避免数据库被占用,并确认版本兼容性。

怎么用 System.Data.SQLite 读取本地 .db 文件
直接装 NuGet 包 System.Data.SQLite(不是 System.Data.SQLite.Core,后者缺设计时支持),然后用标准 ADO.NET 流程就行。别碰 Microsoft.Data.Sqlite——它默认不支持加密、不兼容旧版 SQLite 数据库,且对 Windows Forms 设计器支持弱。
- 连接字符串必须写全路径,相对路径容易崩:
"Data Source=C:appdata.db;Version=3;" -
SQLiteConnection不支持ConnectionStringBuilder的所有属性,比如不能用Pooling=true后还手动调Close(),否则可能卡住连接池 - 如果数据库被其他进程(比如 DB Browser)锁着,
Open()会直接抛SQLiteException,错误信息是"database is locked",不是超时——得关掉别的工具再试
为什么 ExecuteReader() 返回空结果但没报错
常见于表名或字段名大小写不一致,或者用了保留字当列名但没加引号。SQLite 默认是大小写敏感的,而且不校验字段是否存在,直到真正读数据才出问题。
- 执行
SELECT * FROM User失败?试试SELECT * FROM "User"——User是 SQLite 保留字,不加双引号会语法错 - 建表时用
CREATE TABLE logs (Id INTEGER, TimeStamp TEXT),但代码里写reader["timestamp"]就取不到值,因为字段名是TimeStamp,大小写必须完全一致 - 用
PRAGMA table_info(your_table)查下实际字段名和类型,别信自己记的
本地存轻量数据,该用 INSERT OR REPLACE 还是 UPSERT
SQLite 3.24+ 支持 UPSERT,但 C# 项目若目标框架是 .NET Framework 4.7.2 或更老,很可能连带用的是旧版 SQLite 库(比如 1.0.109),根本不识别 UPSERT 语法,直接报 "near "ON": syntax error"。
- 安全起见,统一用
INSERT OR REPLACE INTO,它在所有版本都有效 - 注意:它会删原行再插新行,触发
DELETE和INSERT触发器,自增主键可能变;而UPSERT是就地更新,主键不变 - 如果真要用
UPSERT,先确认System.Data.SQLite版本 ≥ 1.0.115,且 SQLite 运行时版本 ≥ 3.24.0(查SELECT sqlite_version())
为什么程序重启后数据“消失”了
最常见原因是连接字符串里漏了 Data Source= 的绝对路径,或者用了 |DataDirectory| 但没设置 AppDomain.CurrentDomain.SetData("DataDirectory", ……),导致每次都在临时目录新建空库。
- 检查
connection.ConnectionString打印出来是不是你预期的路径,尤其注意有没有C:Users……AppDataLocalTemp这种地方 - 别依赖默认工作目录,C# GUI 程序的工作目录可能是 Visual Studio 安装目录,控制台程序可能是 bin/Debug,都不稳定
- 推荐写死路径:用
Path.Combine(AppContext.BaseDirectory, "data.db"),确保跟 exe 在一起
SQLite 的坑不在语法多难,而在路径、大小写、版本、锁机制这些细节上一踩一个准。尤其是多人协作时,有人用 DB Browser 开着库,有人在代码里狂读写,谁也看不出错在哪。