简介:一份面向C#初、中级开发者的VS2005与Access数据库开发经典案例合集,以光盘内容打包形式发布,聚焦桌面数据库应用开发中的常见功能场景,适合课程设计、毕业设计或日常练手参考。资源以zip格式压缩,整体大小约11.51MB,便于下载解压使用;平台暂未提供具体文件总数与类型清单,学习时可结合案例主题逐一实践。目前已有255人学习下载。借助这套案例,读者可以了解VS2005下C#连接Access数据库的基本流程,学习窗体界面设计、数据绑定、增删改查以及简单报表输出等典型实现方式,也能通过案例代码反推项目组织思路与分层调用方式,减少从零搭建框架的时间。无论用于毕业设计模块参考,还是想快速积累数据库交互开发经验,都能从中找到可迁移的写法与调试思路。
1. 为什么我还在翻 VS2005 和 Access 这套老组合
收到“vs#2005Access数据库开发经典案例——光盘”这张光盘的人,多半是正在维护十年前的内部管理系统,或者是课程设计被指定了 VS2005 环境。第一反应会是:都什么年代了还碰这套?但真正上手就会发现,VS2005 配 Access 数据库做小型管理系统,至今仍有一批未被替代的场景——单机部署、数据文件随拷贝带走、不需要安装数据库服务端。把光盘里的经典案例跑通,等于拿到了一个人家调试好的骨架,后面改表、加窗体、套报表都是往骨架上添肉。这篇文章会告诉你光盘里究竟是什么、第一步怎么把它跑起来、哪些参数必须改、以及 64 位新电脑上最要命的那几个坑。适合两类人:一类是刚拿到光盘不知道怎么下手的初学者,另一类是接手老系统、想从案例里翻出可用代码的维护工程师。
2. 光盘里到底装了什么:拆案例目录,认清数据库和引擎
2.1 光盘案例的典型目录结构与数据库类型
这类图书配套光盘最标准的组织方式,是根目录下按章节或按功能划分子文件夹,每个子文件夹对应一个完整案例;案例里面又是 WebSite、BIN、App_Data 这样的固定骨架。以我拿到过的几张同类光盘来说,目录大致是这样:
光盘根目录 ├── 第03章_学生信息管理 │ ├── 学生信息管理.sln │ ├── 学生信息管理 │ │ ├── App_Code │ │ ├── App_Data │ │ │ └── Student.mdb │ │ ├── Images │ │ ├── Web.config │ │ ├── Default.aspx │ │ └── ... │ └── 说明.txt ├── 第04章_图书借阅系统 └── 第05章_人事工资管理第一个要认清的概念是:光盘里的数据库文件通常有两种后缀,.mdb(Jet 4.0 格式)和.accdb(ACE 格式)。VS2005 时代绝大多数书写的是 .mdb,因为当时 Office 2003 自带的就是 Jet 4.0 驱动,Access 2007 之后的 .accdb 格式在 VS2005 里不能用 OleDb 直接连,需要另装 ACE 驱动,后面我会单独讲。打开某个案例的 App_Data 文件夹,如果只有 .mdb,那这是个典型的 Jet 数据库;如果同时有 .bak,那只是备份,不是运行库。
光盘文件本身是只读介质,这是后面一半坑的源头。把整个案例文件夹复制到硬盘时,Windows 会保留只读属性,VS2005 加载解决方案后编译没问题,但一运行写操作就会炸。所以拿到光盘第一件事不是打开 .sln,而是先复制、再去掉只读。建议用命令行一步到位:
xcopy D:\光盘根目录\第03章_学生信息管理 C:\KfCase\学生信息管理 /E /I /Y attrib -R -S -H C:\KfCase\学生信息管理 /S /D这段命令的作用是把某个案例整体复制到 C 盘,然后递归去掉所有文件的只读、系统、隐藏属性。注意attrib的三个参数顺序不要写错,/S表示对子目录生效,/D表示连文件夹属性一起处理,缺一个都不彻底。复制到 C 盘而不是桌面或网络盘,是避免路径过长触发 VS2005 的“路径太长无法保存”问题,这是老版本 IDE 的一个硬限制。
2.2 认清 Web 项目与 Windows 项目的差别
光盘里的案例分两种:ASP.NET Web 项目和 Windows Forms 项目。用 VS2005 打开时,.sln文件在哪一层直接决定你能否正常加载。常见翻车是把解决方案文件在资源管理器里双击,结果 VS 只打开了文件列表,没进入调试状态。
我的习惯是先看根目录有没有.sln,有则用 VS2005 的“文件→打开→项目/解决方案”去选它;没有.sln只有.csproj(或.vbproj)的,直接用打开项目选 .csproj 也能编译。Web 项目还要注意 VS2005 的 Web 项目有两种模式:文件系统项目和 IIS 项目。光盘案例如果是 IIS 模式,而新机器没有配置 IIS,打开时会报“无法创建 Web 项目”,这时候要么在 VS 里改成文件系统方式,要么去控制面板装 IIS 组件。改文件系统方式的操作路径是:右键解决方案→属性→启动选项→使用自定义服务器,把 URL 指向http://localhost/案例名,但这要求你已经在 IIS 里建了虚拟目录。嫌麻烦的话,直接把 Web 项目源码新建一个文件系统网站再导入文件,比折腾 IIS 快得多。
不过要强调的是,这类书里的案例九成是 Web 项目,因为 Access 在单机管理系统场景里天然适合网页界面,部署时只需把整个文件夹丢到服务器上。
2.3 随盘数据库的驱动选型:Jet 4.0 与 ACE 的边界
这块属于“参数搞错就全军覆没”的部分。VS2005 默认连接 .mdb 的连接字符串是这样写的:
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\KfCase\App_Data\Student.mdbJet 4.0 这个驱动是 32 位,也是 VS2005 自带的。问题在于新电脑 64 位系统上,32 位进程能加载它,64 位进程加载不了,于是程序一运行就报“未找到提供程序”。常见做法是给 ACE 驱动,连接字符串改成:
Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\KfCase\App_Data\Student.mdbACE 是 Access 2007 以后的驱动,既可访问 .mdb 也可访问 .accdb,需要单独安装,微软的下载站就能找到。ACE 有 32 位和 64 位两个版本,选错同样报错。如果项目属于“只能装 Office 32 位”的机器,那就装 32 位 ACE,并且把 VS 2005 的编译目标从 AnyCPU 改成 x86。改法是项目属性→生成→平台目标→x86,这条我会在第 5 章避坑里展开,这里先记住结论:VS2005 配 Access,先看系统位数,再定驱动位宽,再写连接字符串,顺序不能反。
3. 跑通第一个经典案例:连接字符串、数据绑定与最小命令
3.1 在 Visual Studio 2005 里建立数据库连接的两种路径
打开光盘案例后,想确认数据库连接是否真的通,最直接的办法不是运行整个网站,而是先加一个“数据源”测试连接。VS2005 自带服务器资源管理器,右键“数据连接→添加连接”,数据源选“Microsoft Access 数据库文件”,然后浏览到 .mdb 文件。如果测试连接成功,说明驱动、文件、权限三条链路没问题;失败则按提示看是哪一环断了——这里能区分出“驱动没装”和“文件被占用”两种完全不同的错。
代码层面建立连接则更可控。我一般会在 App_Code 里放一个公共类,把连接字符串集中管理,而不是散落在每个页面里。连接字符串里最重要的两个参数是 Provider 和 Data Source,前者选驱动,后者指文件路径。路径最好用App_Data相对路径,这样案例换个机器不用改代码,只用改配置:
public static string GetConnectionString() { string mdbPath = HttpContext.Current.Server.MapPath("~/App_Data/Student.mdb"); return "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + mdbPath + ";Persist Security Info=True"; }这段代码的用意是把物理路径交给 MapPath 去解析,因为网页里你永远不知道网站被部署在哪个盘。Persist Security Info=True 表示连接成功后保留密码信息,如果 .mdb 文件本身没设置密码,这个参数写不写都行;但给带密码的库写漏了,就会一直报“无法启动应用程序”。所以拿到光盘案例先看数据库有没有加密:用 Access 或打开库看一眼,如果提示要密码,就把Jet OLEDB:Database Password=你的密码追加在连接字符串末尾。
3.2 DataGridView 或 GridView 绑定 Access 表的最小代码
经典案例里最开场的那一步,是把一张表的数据显示到界面上。Web 端用的是 GridView,Windows 端是 DataGridView,但底层套路一致:OleDbDataAdapter 取数据→填充 DataTable→绑定数据源。给你看一个最小可运行的 C# Web 示例:
using System.Data; using System.Data.OleDb; public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { BindGrid(); } } private void BindGrid() { string connStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Server.MapPath("~/App_Data/Student.mdb"); string sql = "SELECT 学号, 姓名, 班级 FROM 学生表 ORDER BY 学号"; DataTable dt = new DataTable(); using (OleDbConnection conn = new OleDbConnection(connStr)) { using (OleDbDataAdapter da = new OleDbDataAdapter(sql, conn)) { da.Fill(dt); } } GridView1.DataSource = dt; GridView1.DataBind(); } }逻辑说明:using是为了确保连接对象用完即关,避免 Access 数据库文件被锁住。OleDbDataAdapter.Fill负责执行查询并填充 DataTable,你不用手动 Open/Close 连接,Fill 内部会自动处理连接状态。参数说明:SQL 语句里的中文字段名在 Access 里是允许的,但字符串拼接时要注意数据库表名是否存在;ORDER BY 一个编号字段能保证显示顺序稳定,否则每次查询返回顺序可能不一致。GridView 的 AutoGenerateColumns 默认是 true,字段自动匹配,省去了手工绑定列的麻烦。
3.3 参数化增删改查:不要拼 SQL 字符串
经典案例里最容易误入歧途的地方,是增删改查全用字符串拼接,比如把文本框内容直接塞进 SQL。初看能跑,但遇到带单引号的文本、中文模糊查询、或日期格式变化时就翻车。VS2005 时代的 OleDb 参数化和 SqlClient 参数化有个明显差异:OleDbCommand 的参数不能用命名参数匹配,必须按顺序 Add。看这个插入示例:
string sql = "INSERT INTO 学生表(学号, 姓名, 班级) VALUES(?, ?, ?)"; using (OleDbConnection conn = new OleDbConnection(connStr)) { using (OleDbCommand cmd = new OleDbCommand(sql, conn)) { cmd.Parameters.Add("@学号", OleDbType.VarChar).Value = txtNo.Text.Trim(); cmd.Parameters.Add("@姓名", OleDbType.VarWChar).Value = txtName.Text.Trim(); cmd.Parameters.Add("@班级", OleDbType.VarWChar).Value = txtClass.Text.Trim().Length == 0 ? "未分班" : txtClass.Text.Trim(); conn.Open(); cmd.ExecuteNonQuery(); } }这里的?占位符是 OleDb 的固定写法,参数名在 SQL 里写 @学号 不会生效,但正常能识别。为什么代码里还写 @ 学号?这是为了可读性,提醒我和你哪个参数对应哪个字段,Add 顺序必须和?顺序一致。OleDbType.VarChar 对应 Access 的文本类型;注意 Access 的“文本”最多 255 字符,超长会报错。ExecuteNonQuery 返回影响行数,可以用来判断是否插入成功,但更好的校验是让 Access 主键自己报错,别在代码里先查一遍。
4. 把经典案例改造成自己能用:三层写法和数据访问封装
4.1 从案例里提炼数据访问层:OleDbHelper 的样板
光盘案例的代码风格通常是“页面里全干完”,一个 aspx.cs 文件里又是查表又是拼 SQL。这拿来学习没问题,一旦要往里面加功能就会失控。我的做法是从案例里把重复的连接、查询、执行逻辑抽到一个公共类里,形成所谓数据访问层。这里给出一个适配 VS2005 环境的最小 OleDbHelper:
public static class OleDbHelper { private static string connStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + HttpContext.Current.Server.MapPath("~/App_Data/Student.mdb"); public static DataTable ExecuteTable(string sql, params OleDbParameter[] paras) { DataTable dt = new DataTable(); using (OleDbConnection conn = new OleDbConnection(connStr)) { using (OleDbCommand cmd = new OleDbCommand(sql, conn)) { if (paras != null) cmd.Parameters.AddRange(paras); using (OleDbDataAdapter da = new OleDbDataAdapter(cmd)) { da.Fill(dt); } } } return dt; } public static int ExecuteNonQuery(string sql, params OleDbParameter[] paras) { using (OleDbConnection conn = new OleDbConnection(connStr)) { using (OleDbCommand cmd = new OleDbCommand(sql, conn)) { if (paras != null) cmd.Parameters.AddRange(paras); conn.Open(); return cmd.ExecuteNonQuery(); } } } }这套封装的优点是调用方只关心 SQL 和参数,不碰连接生命周期;缺点也很明显——连接字符串写死在类里,换数据库文件就得改代码。改进方法是把连接字符串挪到 Web.config 的 appSettings 里,再用 ConfigurationManager.AppSettings 读取。VS2005 对应 .NET 2.0,记得在文件头部using System.Configuration;,否则 AppSettings 取不出来。
4.2 案例移植时最容易忽略的表结构问题
不同案例的数据库表结构差异很大,最典型的是“自增主键”和“自动编号”。Access 里的自动编号字段默认从 1 开始,但在案例里如果做过删除测试,种子会越跳越大,这是正常现象。往新库导数据时,千万别把旧库的自动编号值一并导入,否则 Access 会拒绝导入或产生冲突。正确做法是只导入业务字段,让主键重新生成。
另一个是字段类型不匹配问题:案例库里某些列是“是/否”类型(布尔),对应 OleDbType.Boolean;在界面上它显示为复选框,但 SQL 里判断要写WHERE 是否启用 = True,而不是= 1。字符串匹配在 Access 里默认不区分大小写,这对查询来说是好事,但精确查找时容易把不同大小写的值混在一起,需要精确匹配时可以用StrComp函数或把字段排序规则改为区分大小写——这里知道有坑即可,案例需求一般碰不到。
4.3 为案例加一个简单搜索页:参数化模糊查询
模糊查询是这类管理系统的标配,也是初学者最爱翻车的一处。Access 的 LIKE 语法对 OleDb 参数支持有特殊性:参数位置在 LIKE 后面占位时,通配符必须放在参数值里,而不是写进 SQL。以下代码实现按姓名和班级两个条件搜索:
string sql = "SELECT 学号, 姓名, 班级 FROM 学生表 WHERE (姓名 LIKE ? OR 班级 LIKE ?) ORDER BY 学号"; OleDbParameter p1 = new OleDbParameter("@姓名", OleDbType.VarWChar); p1.Value = "%" + txtKeyword.Text.Trim() + "%"; OleDbParameter p2 = new OleDbParameter("@班级", OleDbType.VarWChar); p2.Value = "%" + txtKeyword.Text.Trim() + "%"; DataTable dt = OleDbHelper.ExecuteTable(sql, p1, p2); GridView1.DataSource = dt; GridView1.DataBind();参数说明:这里的%是 Access 的通配符,不是 SQL Server 的*,如果你写成*关键字*是查不出来的。两个参数共用一个关键字,但必须声明两次参数对象,不能复用一个参数实例,因为 AddRange 会按索引绑定。查询结果为空时 GridView 只显示表头,我想让它显示一行“无匹配记录”,可以给 GridView 设置 EmptyDataText 属性,这一行字不用写任何 C# 代码。
5. 避坑:VS2005 + Access 的常见翻车现场与排查
5.1 64 位系统报“未找到提供程序 Microsoft.Jet.OLEDB.4.0”
现象:光盘案例在 Win7/10 的 64 位系统上一编译能过,一运行就抛异常:未找到提供程序,或未注册的 COM 组件。原因是 Jet 4.0 只有 32 位版本,而你的应用程序池或进程以 64 位模式运行,系统在 64 位环境里找不到这个 32 位驱动。解决:首选给 64 位系统安装 Microsoft Access Database Engine(ACE),然后用 ACE 替换驱动名;但如果机器已经装了 32 位 Office,64 位 ACE 会装不上,此时反过来把项目(或 IIS 应用程序池)改成 32 位。VS 2005 的项目设置里,把“平台目标”从 AnyCPU 改为 x86,重新生成即可。
5.2 运行时报“操作必须使用一个可更新的查询”
现象:程序能读出数据,只要一执行插入、更新、删除就报错,错误文本是“操作必须使用一个可更新的查询”。原因绝大多数不是 SQL 写错,而是 Access 数据库文件所在目录没有写权限,或者 .mdb 文件本身被标记为只读。光盘复制出来忘记去掉只读属性,就会这样。解决:确认 .mdb 文件属性不是只读;再把整个 App_Data 目录给当前用户或 IIS_IUSRS 加“写入”权限。还有一个隐蔽原因,是用 Access 打开数据库后没关闭,文件被独占锁定,此时把 Access 关掉再试。
5.3 光盘源码复制后编译失败和断点不命中
现象:从光盘把整个案例拷到本地硬盘,直接用 VS2005 打开,编译时报错,或者能跑但 F9 断点显示不会被命中。原因一:光盘文件的只读属性导致 VS 无法生成临时文件;原因二:路径太深,比如D:\我的文档\桌面\光盘\第03章_学生信息管理\学生信息管理\App_Data\Student.mdb,VS2005 对长路径的容忍度很低。解决:先执行第 2 章的 attrib 命令去掉只读,把整个案例放在短路径下,比如C:\KfCase\学生信息管理,然后执行“生成→清理解决方案”再重新生成。断点不命中时,检查是否开了“启用仅我的代码”,以及 Web.config 里是否处于 Debug 编译模式。
5.4 中文检索查不出结果,或保存后显示乱码
现象:根据文本框输入的中文去查询,返回空;写入的中文重新显示变成“?”。第一个情况通常是 SQL 用了LIKE '%值%'但参数绑定错误,OleDb 要求占位符?与参数对象按顺序对应,参数名随意但顺序不能乱。第二个情况“?”说明数据传输时字符集出了问题,.mdb 文件的 Access 默认文本编码在少数系统上会乱,解决办法是在连接字符串里追加;Locale Identifier=2052,强制使用简体中文区域。写入乱码还有一个常见来源:aspx 页面编码不是 UTF-8,把<%@ Page ... %>指令里的编码改成utf-8,并在 Web.config 里统一 globalization 配置。
5.5 解决方案文件打不开,提示“项目文件已损坏”
现象:双击 .sln 后 VS2005 提示项目文件损坏或无法加载。原因往往是解决方案文件里保存的路径是光盘时代的绝对路径,比如D:\光盘\...,而你现在放到 C 盘,VS 按旧路径找不到项目就误报损坏。解决:不要打开 .sln,而是直接打开对应案例文件夹里的.csproj或.vbproj项目文件;如果项目文件也指向旧路径,用记事本打开 .sln 手动改掉里面的绝对路径行。还有一种情况是案例用了 VS2008 以上语法建的项目文件,VS2005 打开会提示“需要较新版本的 Visual Studio”,这种只能换 VS2008 或更高版本打开,不在案例可修范围内。
6. 让老案例在新电脑上跑起来:迁移与验证的三个习惯
把光盘案例跑通只是第一步,真正值钱的是让它成为你可以反复修改的骨架。我给自己定了一套固定流程,每次接手这种老案例都这么做:先看系统位数,再决定驱动;先跑一次查询确认连接,再动改代码;先把数据文件备份,再动表结构。这三条顺序错一条,排查时间翻一倍。
一个比较实用的升级路径是:将 .mdb 用 Access 另存为 .accdb,连接字符串换成 Microsoft.ACE.OLEDB.12.0,这样不仅支持 2007 格式,还能用到更稳定的 ACE 引擎。但注意 .accdb 文件无法在 Win7 之前的环境直接用,迁移前确认目标机器装过 ACE。
验证工作也别只靠眼睛。我会在页面里加一截极短的诊断代码,比如让 GridView 绑定SELECT COUNT(*) AS 总数 FROM 学生表,能正常显示数字就说明连接、驱动、权限全通过了。这一步看似多余,但它能在你改完连接字符串后立刻分辨出到底是配置问题还是代码问题,省掉大量来回测试的时间。
最后说个我自己的教训:当年帮某公司迁移这批案例,图省事没做旧库备份,直接在新库里改了字段类型,结果所有带日期的查询全部错乱,花了整整一个晚上才用备份恢复。从那以后,凡是要动 Access 表结构,我必先在 App_Data 里复制一份 .mdb 再动手。这个习惯救过我很多次,希望也能帮到你。
本文还有配套的精品资源,点击获取