1、前置环境
安装 SQLite 软件包:点击工具栏工具 > NuGet 包管理器 > 程序包管理器控制台 :

在控制台输入下载命令:
Install-Package System.Data.SQLite.Core
说明:
System.Data.SQLite.Core是 .NET Framework / WinForms 项目的首选包,安装后自动携带 32/64 位原生引擎SQLite.Interop.dll。- 也可以走「工具 > NuGet 包管理器 > 管理解决方案的 NuGet 程序包」图形界面搜索安装,效果相同。
- 不需要同时安装
Microsoft.Data.Sqlite、SQLitePCLRaw.*,两套驱动混装会导致无法加载 DLL"e_sqlite3"报错。
2、数据的建立
核心思路:SQLite 的"建库"就是创建一个文件,连接串指向的文件不存在时会自动创建;表结构用 CREATE TABLE IF NOT EXISTS 在程序启动时执行一次,重复运行不会报错也不会清数据。
具体步骤:
(1)新建一个类文件 Db.cs,引入命名空间:
using System.Data.SQLite;
using System.IO;
using System.Windows.Forms; // 用到 Application.StartupPath
(2)定义数据库文件路径与连接字符串:
// 数据库文件放在程序运行目录(bin\Debug)下
private static readonly string DbPath =
Path.Combine(Application.StartupPath, "myapp.db");
private static readonly string ConnStr =
"Data Source=" + DbPath + ";Version=3;";
Data Source指向.db文件路径;Version=3表示使用 SQLite 3 协议。
(3)封装获取连接的方法(用完即关,SQLite 连接开销极小):
public static SQLiteConnection GetConnection()
{
var conn = new SQLiteConnection(ConnStr);
conn.Open();
return conn;
}
(4)编写初始化方法,执行建表 SQL:
public static void Init()
{
using (var conn = GetConnection())
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = @"CREATE TABLE IF NOT EXISTS ...";
cmd.ExecuteNonQuery();
}
}
(5)在程序入口最先调用一次 Init()(Program.cs):
[STAThread]
static void Main()
{
Db.Init(); // 建库 + 建表,必须放在窗体启动之前
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new For());
}(6)运行程序,`bin\Debug\` 目录下出现 `myapp.db`,建库完成。
整体代码参考:
public static class Db
{
// 数据库文件放在程序目录下
private static readonly string DbPath =
Path.Combine(Application.StartupPath, "myapp.db");
private static readonly string ConnStr =
"Data Source=" + DbPath + ";Version=3;";
// 获取连接(每次操作用完即关,SQLite 开销很小)
public static SQLiteConnection GetConnection()
{
var conn = new SQLiteConnection(ConnStr);
conn.Open();
return conn;
}
// 程序启动时调用一次:建库 + 建表
public static void Init()
{
using (var conn = GetConnection())
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = @"
CREATE TABLE IF NOT EXISTS Users (
Id INTEGER PRIMARY KEY AUTOINCREMENT,
UserName TEXT NOT NULL UNIQUE,
Password TEXT NOT NULL,
Phone TEXT,
CreatedAt TEXT DEFAULT (datetime('now','localtime'))
);
CREATE TABLE IF NOT EXISTS Orders (
Id INTEGER PRIMARY KEY AUTOINCREMENT,
UserId INTEGER NOT NULL,
Amount REAL NOT NULL,
Status TEXT DEFAULT '待处理',
FOREIGN KEY (UserId) REFERENCES Users(Id)
);";
cmd.ExecuteNonQuery();
}
}
}
3、数据库的访问
固定套路:Db.GetConnection() 拿连接 → 建 Command → 写 SQL(参数化)→ 执行 → using 自动释放。
(1)查询:填充到 DataGridView
private void LoadUsers()
{
using (var conn = Db.GetConnection())
using (var da = new SQLiteDataAdapter(
"SELECT Id AS 编号, UserName AS 用户名, Phone AS 电话, CreatedAt AS 创建时间 FROM Users ORDER BY Id",
conn))
{
var dt = new DataTable();
da.Fill(dt); // 执行查询并填充
dgvUsers.DataSource = dt; // 绑定显示
}
}
(2)插入:注意 @参数 占位,禁止字符串拼接
using (var conn = Db.GetConnection())
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = "INSERT INTO Users(UserName, Password, Phone) VALUES(@u, @p, @ph)";
cmd.Parameters.AddWithValue("@u", txtName.Text.Trim());
cmd.Parameters.AddWithValue("@p", "123456");
cmd.Parameters.AddWithValue("@ph", txtPhone.Text.Trim());
int rows = cmd.ExecuteNonQuery(); // 返回受影响行数
}
(3)修改:
using (var conn = Db.GetConnection())
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = "UPDATE Users SET Phone=@ph WHERE Id=@id";
cmd.Parameters.AddWithValue("@ph", txtPhone.Text.Trim());
cmd.Parameters.AddWithValue("@id", id);
cmd.ExecuteNonQuery();
}
(4)删除:
using (var conn = Db.GetConnection())
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = "DELETE FROM Users WHERE Id=@id";
cmd.Parameters.AddWithValue("@id", id);
cmd.ExecuteNonQuery();
}
(5)查询单个值(登录校验、统计等):
using (var conn = Db.GetConnection())
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = "SELECT COUNT(*) FROM Users WHERE UserName=@u AND Password=@p";
cmd.Parameters.AddWithValue("@u", txtName.Text.Trim());
cmd.Parameters.AddWithValue("@p", txtPwd.Text.Trim());
long count = (long)cmd.ExecuteScalar(); // 返回第一行第一列
if (count > 0) MessageBox.Show("登录成功");
}
三种执行方式的区别:
| 执行方法 | 适用场景 | 返回值 |
|---|---|---|
ExecuteNonQuery() | INSERT / UPDATE / DELETE、建表 | 受影响行数 |
ExecuteScalar() | COUNT / MAX / 取单个字段 | 第一行第一列(object,需强转) |
ExecuteReader() / SQLiteDataAdapter.Fill() | SELECT 多行多列 | 读取器 / DataTable |
4、验证与查看数据
.db 文件不能用记事本或 Visual Studio 直接打开(是二进制文件,打开是乱码),需用专用工具:
- DB Browser for SQLite(免费开源,https://sqlitebrowser.org):打开
bin\Debug\myapp.db,「数据库结构」页看表、「浏览数据」页看记录。 - 查看前建议先关闭程序,避免 SQLite 文件锁导致
database is locked。
5、常见问题
(1)System.DllNotFoundException:无法加载 DLL"e_sqlite3"
原因是项目里混装了两套 SQLite 驱动,或原生 DLL 未复制到输出目录。处理:卸载全部 SQLite 相关包后只装一个。
Uninstall-Package Microsoft.Data.Sqlite -Force
Uninstall-Package SQLitePCLRaw.bundle_e_sqlite3 -Force
Uninstall-Package SQLitePCLRaw.core -Force
Install-Package System.Data.SQLite.Core
生成后确认 bin\Debug\x86\SQLite.Interop.dll 与 bin\Debug\x64\SQLite.Interop.dll 均存在。
(2)no such table: Users
Db.Init() 没有被调用,或调用晚于查询。确认它在 Program.Main() 的第一行。
(3)database is locked
另一个进程(如 DB Browser)占用了文件,或连接未关闭。坚持用 using 包裹连接。
(4)数据被清空/表丢失
不要用 CREATE TABLE(无 IF NOT EXISTS)加 DROP TABLE 的组合做初始化;也不要把 bin\Debug\myapp.db 当作"临时文件"删除——它就是正式数据。
6、要点汇总
- SQLite 是嵌入式数据库,无需安装 SQL Server、MySQL 等数据库服务,NuGet 装包即可。
- 建库 = 建文件,连接串指向的
.db不存在时自动创建。 - 建表语句必须带
IF NOT EXISTS,保证程序重复启动安全。 - SQL 值一律用
@参数+AddWithValue,防注入、防单引号报错。 - 连接一律
using包裹,用完即关。 - 数据库文件随程序发布,拷到任何 Windows 电脑可直接运行,无需配环境。
转载自 CSDN-专业IT技术社区
原文链接:https://blog.csdn.net/2301_80809484/article/details/170048500



