数据库 · Access
开发专题 · OleDb Jet/ACE 提供程序、连接字符串与增删改查 API
本页说明如何在 .NET Framework 4.8 窗体(或控制台)项目中通过 OleDb 访问 Microsoft Access(.mdb / .accdb):在 LCode 中确认引用、选择 Jet 或 ACE 提供程序、编写连接字符串,以及用 ADO.NET 完成增删改查。操作文案以 LCode 中文界面为准;凡有代码均同时给出 C# 5.0 与 VB.NET。DataGridView 绑定、行编辑与自定义列见 数据表单与自定义列(本页不重复整页网格 UI);同一项目使用多个 Access 库文件见 多数据源(多 Access 库文件)。
引用哪些 DLL / NuGet 或本地程序集
推荐使用框架自带的 ADO.NET 提供程序 System.Data.OleDb(命名空间同名)。在 .NET Framework 4.8 上,类型位于 System.Data 程序集,窗体模板一般已默认引用;真正连上 Access 还依赖本机已注册的 Jet 或 ACE OLE DB 提供程序(非托管驱动,不是再下一个托管 NuGet 就能替代)。
| 文件 / 项 | 作用 |
|---|---|
System.Data.dll / System.Data.OleDb |
框架程序集;OleDbConnection、OleDbCommand、OleDbDataReader、OleDbDataAdapter 等。在 LCode 中添加.NET 程序集引用(多数模板已有) |
Microsoft.Jet.OLEDB.4.0 |
经典 Jet 提供程序,惯用于 .mdb。仅为 32 位;工程宜 x86,或 AnyCPU 勾选「首选 32 位」。LCode 示例工程(如 OrderManage)常用此提供程序 |
Microsoft.ACE.OLEDB.12.0(或本机已装的更高 ACE) |
Access Database Engine,可读 .mdb / .accdb。须单独安装引擎,且位数与进程一致(x86 进程配 x86 引擎,x64 配 x64) |
NuGet 包 System.Data.OleDb |
面向跨目标框架的独立包(常见于较新栈)。本手册以 .NET Framework 4.8 自带程序集为准。LCode 主界面 NuGet 包管理暂不支持,待更新完善——若你坚持用 NuGet 发行版,请在外部还原后再浏览引用 DLL |
在 LCode 中添加引用
- 在项目浏览器中选中窗体(或控制台)项目 → 右键 → 添加引用(或菜单 项目 → 添加引用)。
- 在 .NET 页签中勾选
System.Data→ 确定(若已引用可跳过)。 - 在代码文件顶部加入
using System.Data.OleDb;(C#)或Imports System.Data.OleDb(VB.NET)。 - 确认目标机 / 开发机已具备 Jet(随多数系统或 Office 相关组件)或已安装对应位数的 Access Database Engine(ACE)。
- 菜单 编译 → 编译解决方案(F8),确认无「找不到类型或命名空间」错误;再在运行时验证
Open能连上库文件。
System.Data 一般无需设「本地复制」;Jet/ACE 是本机 OLE DB 提供程序,部署时目标机也须具备对应引擎。
连接字符串
Access 连接串的核心是 Provider(Jet 或 ACE)与 Data Source(库文件路径)。可选 Jet OLEDB:Database Password(库口令)等。路径建议用 Application.StartupPath 拼绝对路径,避免工作目录变化导致找不到文件。
| 连接字符串示例 | 说明 |
|---|---|
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Data\app.mdb; |
.mdb + Jet;进程须为 32 位 |
Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Data\app.accdb; |
.accdb(或 .mdb)+ ACE;引擎位数与进程一致 |
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=…\app.mdb;Jet OLEDB:Database Password=秘密; |
带库口令的 Jet;勿把口令写死进公开仓库 |
Provider=Microsoft.ACE.OLEDB.12.0;Data Source=…\app.accdb;Persist Security Info=False; |
ACE 常用附加键示例;具体键以本机提供程序文档为准 |
using System.Data.OleDb;
using System.IO;
using System.Windows.Forms;
// 库文件放在 EXE 旁 Data 目录(.mdb + Jet 示例)
string dbPath = Path.Combine(Application.StartupPath, "Data", "app.mdb");
string connStr =
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + dbPath + ";";
using (OleDbConnection conn = new OleDbConnection(connStr))
{
conn.Open();
// …执行命令…
}
Imports System.Data.OleDb
Imports System.IO
Imports System.Windows.Forms
' 库文件放在 EXE 旁 Data 目录(.mdb + Jet 示例)
Dim dbPath As String = Path.Combine(Application.StartupPath, "Data", "app.mdb")
Dim connStr As String =
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & dbPath & ";"
Using conn As New OleDbConnection(connStr)
conn.Open()
' …执行命令…
End Using
增删改查
以下示例假定库文件已存在,表 Items 将按「建表」语句创建(或已预先建好)。OleDb 对 Jet/ACE 的参数占位符请用 ?,并按出现顺序 Parameters.Add;参数名本身通常不影响绑定顺序。类名以 System.Data.OleDb 为准(OleDbConnection、OleDbCommand、OleDbParameter、OleDbDataReader)。
建表(首次)
Access 的 DDL 与 SQL Server / SQLite 不同:常见用 COUNTER(自动编号)、TEXT(n)、LONG 等。没有通用的 IF NOT EXISTS;表已存在时再次执行会失败,可事先用 Access 建好表,或在代码里捕获异常后忽略「已存在」。
const string SqlCreate =
"CREATE TABLE Items (" +
"Id COUNTER PRIMARY KEY, " +
"Name TEXT(100) NOT NULL, " +
"Qty LONG NOT NULL);";
using (OleDbCommand cmd = new OleDbCommand(SqlCreate, conn))
{
cmd.ExecuteNonQuery();
}
Const SqlCreate As String =
"CREATE TABLE Items (" &
"Id COUNTER PRIMARY KEY, " &
"Name TEXT(100) NOT NULL, " &
"Qty LONG NOT NULL);"
Using cmd As New OleDbCommand(SqlCreate, conn)
cmd.ExecuteNonQuery()
End Using
插入(Create)
using (OleDbCommand cmd = new OleDbCommand(
"INSERT INTO Items (Name, Qty) VALUES (?, ?);", conn))
{
cmd.Parameters.AddWithValue("@p1", "螺丝");
cmd.Parameters.AddWithValue("@p2", 100);
cmd.ExecuteNonQuery();
}
Using cmd As New OleDbCommand(
"INSERT INTO Items (Name, Qty) VALUES (?, ?);", conn)
cmd.Parameters.AddWithValue("@p1", "螺丝")
cmd.Parameters.AddWithValue("@p2", 100)
cmd.ExecuteNonQuery()
End Using
查询(Read)
using (OleDbCommand cmd = new OleDbCommand(
"SELECT Id, Name, Qty FROM Items ORDER BY Id;", conn))
using (OleDbDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
int id = reader.GetInt32(0);
string name = reader.GetString(1);
int qty = reader.GetInt32(2);
Console.WriteLine(id + "\t" + name + "\t" + qty);
}
}
Using cmd As New OleDbCommand(
"SELECT Id, Name, Qty FROM Items ORDER BY Id;", conn)
Using reader As OleDbDataReader = cmd.ExecuteReader()
While reader.Read()
Dim id As Integer = reader.GetInt32(0)
Dim name As String = reader.GetString(1)
Dim qty As Integer = reader.GetInt32(2)
Console.WriteLine(id & vbTab & name & vbTab & qty)
End While
End Using
End Using
更新(Update)
using (OleDbCommand cmd = new OleDbCommand(
"UPDATE Items SET Qty = ? WHERE Id = ?;", conn))
{
cmd.Parameters.AddWithValue("@p1", 120);
cmd.Parameters.AddWithValue("@p2", 1);
int rows = cmd.ExecuteNonQuery();
Console.WriteLine("更新行数: " + rows);
}
Using cmd As New OleDbCommand(
"UPDATE Items SET Qty = ? WHERE Id = ?;", conn)
cmd.Parameters.AddWithValue("@p1", 120)
cmd.Parameters.AddWithValue("@p2", 1)
Dim rows As Integer = cmd.ExecuteNonQuery()
Console.WriteLine("更新行数: " & rows)
End Using
删除(Delete)
using (OleDbCommand cmd = new OleDbCommand(
"DELETE FROM Items WHERE Id = ?;", conn))
{
cmd.Parameters.AddWithValue("@p1", 1);
cmd.ExecuteNonQuery();
}
Using cmd As New OleDbCommand(
"DELETE FROM Items WHERE Id = ?;", conn)
cmd.Parameters.AddWithValue("@p1", 1)
cmd.ExecuteNonQuery()
End Using
OleDbDataAdapter + OleDbCommandBuilder 填充 DataTable,再赋给 DataSource,并用 Update 写回。网格列外观、按钮/图片等自定义列与完整窗体流程见 数据表单与自定义列。
注意事项
| 注意点 | 说明 |
|---|---|
| Jet / ACE 位数 | Jet 4.0 → 32 位进程。ACE 须与进程同为 x86 或 x64;混用会报提供程序未注册或 BadImageFormatException。在 LCode 项目选项中对齐平台目标(及「首选 32 位」)。 |
| 文件路径与部署 | 相对路径依赖当前工作目录。建议 Application.StartupPath 拼绝对路径,并把 .mdb/.accdb 随 EXE 一起复制(例如输出目录下的 Data\)。 |
| 文件锁与独占 | Access 库被 Access 客户端或其他进程独占打开时,Open / 写操作可能失败。开发期先关闭占用该文件的程序。 |
| OleDb 参数顺序 | 占位用 ?,按 SQL 中出现顺序添加参数;不要假设按参数名绑定(与 SqlClient / SQLite 的 @Name 习惯不同)。 |
| SQL 注入 | 用户输入一律走参数,不要字符串拼接进 SQL。 |
| 连接与资源 | 短用短关:优先 using/Using 释放连接、命令与阅读器。长时间占连接不利于多进程共享同一 .mdb。 |
| NuGet / 可视化数据源 | LCode 主界面 NuGet 包管理、以及「可视化数据库设计器 / 数据源向导」针对 Access 的一站式配置暂不支持,待更新完善。请按本页手工引用与手写 ADO.NET;网格 UI 见 数据表单与自定义列。 |
相关阅读
- 数据表单与自定义列 — Access + DataGridView 绑定、增删改与自定义列
- 引用 DLL — 浏览托管程序集、「本地复制」与常见加载错误
- 数据库 · SQLite — 本地文件库对照
- 多数据源(多 Access 库文件) — 同一种 Access、多个库文件
- 运行与编译 — 平台目标、输出目录与运行验证
- C# / VB.NET 窗体应用入门 — 可挂接数据库的窗体侧入门