必须同时安装 microsoft.data.sqlite 和 sqlitepclraw.bundle_e_sqlite3 才能避免 e_sqlite3 dll 加载失败;连接字符串中 datasource=xxx.db 是必需项,路径需匹配运行时输出目录或用 |datadirectory| 并设置 basedirectory;首次运行须手动建表;读取时注意 sqlite 动态类型与 c# 强类型的适配。

安装 SQLitePCLRaw 和 Microsoft.Data.Sqlite
不装对的包,Microsoft.Data.Sqlite 会直接报 System.DllNotFoundException: Unable to load DLL 'e_sqlite3'。这不是缺驱动,是缺原生 SQLite 库。
- 用 NuGet 安装
Microsoft.Data.Sqlite(推荐 8.x 版本,.NET 6+ 兼容性好) -
必须同时安装
SQLitePCLRaw.bundle_e_sqlite3—— 这个包把e_sqlite3动态库带进项目,否则 Windows/macOS/Linux 都跑不起来 - 别装
System.Data.SQLite,它和 .NET Core/.NET 5+ 的运行时加载机制冲突,容易在发布后出错
连接字符串怎么写才不会崩
DataSource=xxx.db 是唯一必需项,但路径处理不当,运行时就找不到文件——尤其在调试和发布后路径行为不一致。
- 用相对路径时,
DataSource=app.db默认找的是AppDomain.CurrentDomain.BaseDirectory,也就是输出目录(如bin/Debug/net8.0/),不是项目根目录 - 想固定存到程序同级目录?写成
DataSource=|DataDirectory|\app.db,并在启动时设置:AppDomain.CurrentDomain.SetData("DataDirectory", AppContext.BaseDirectory) - 如果数据库要随程序一起发布,把
app.db设为“复制到输出目录”,否则发布后app.db根本不存在
执行 INSERT 或 SELECT 前必须检查表是否存在
SQLite 不像 SQL Server 有自动建库建表能力,第一次运行时 SELECT * FROM users 报 SqliteException: no such table: users 是常态,不是代码写错了。
- 别指望 ORM 自动建表(除非你明确配置了
context.Database.EnsureCreated(),且用的是 EF Core +Microsoft.Data.Sqlite) - 手写 SQL 时,先执行建表语句:
CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT) - 注意:SQLite 的
INTEGER PRIMARY KEY自动当 ROWID 用,支持自增;但NOT NULL和默认值得显式写,比如created_at TEXT DEFAULT (datetime('now'))
读取数据时用 SqliteDataReader 还是 ToList()?
小数据量无所谓,但读几千行还用 reader.Read() 手动循环,不如用 Dapper 或 EF Core 封装;可一旦涉及二进制字段(如图片 blob)、或需要精细控制内存,SqliteDataReader 就绕不开。
- 用
reader.GetValue(1)比reader.GetString(1)更安全——SQLite 是动态类型,字段可能为 NULL 或类型不匹配 - 读取 BLOB 字段(如
byte[])时,reader.GetValue(i)返回的是byte[],但若字段为空,返回的是DBNull.Value,不判空直接转数组会炸 - 记得调用
reader.Close()或用using包裹,否则连接不释放,反复查询后可能卡死
实际最难的不是连上,是搞清 SQLite 的“松类型”怎么跟 C# 的强类型对齐——比如一个字段存了 "123" 字符串,又存了 456 整数,GetInt32() 在后者行,在前者就抛异常。这事没法靠工具兜底,得自己在 SQL 层或读取层做归一化。










