简介:这份资源是面向计算机相关专业在校学生与教师的MySQL数据库课程设计完整交付包,以C# WinForm实现房屋租赁管理系统,覆盖房源、租客、账单、财务、管理员等核心业务模块,适合作为课设、大作业或毕设的参考范例。压缩包共71个文件,约12.83MB,包含25个cs源码文件、11个resx与11个resources界面资源、1个sql数据库脚本、1个sln解决方案与csproj工程文件,以及设计报告docx、系统说明doc、ER图与数据流图png、MySQL连接组件msi等,源码、数据库与文档齐备。目前已有303人学习下载。项目代码完整且功能验证通过,可帮助读者理解C#与MySQL的连接方式、数据表设计与窗体交互逻辑,并借助设计报告与图表梳理需求分析、数据库建模到功能实现的完整流程,也便于在此基础上进行二次开发与功能扩展。
1. 从一份房屋租赁管理系统课设说起:C# 与 MySQL 怎么把业务跑通
很多计算机专业的学生在做数据库课设时,第一反应是去搜「房屋租赁管理系统源码」,下载下来发现跑不起来——数据库连不上、表结构对不上、C# 项目缺依赖。这个标题指向的正是一套完整的课设交付物:C# 写的桌面端程序、MySQL 数据库脚本、以及一份设计报告。它解决的核心问题是:如何用一门强类型语言配合关系型数据库,把房东、租客、房源、合同这四类实体的增删改查和业务约束落地成一个能演示、能答辩的系统。
适合谁看?正在做数据库课设的本科生、需要快速搭一个 CRUD 管理系统的初学者、以及想搞清楚 C# 连接 MySQL 完整链路的开发者。热词里频繁出现的「mysql安装配置教程」「c#连接」「数据库增删改查」说明大部分人的卡点不在业务逻辑,而在环境搭建和连接配置。这篇笔记就按「环境准备 → 数据库设计 → C# 数据访问层 → 业务功能实现 → 避坑 → 进阶」的顺序,把每个环节的可复现步骤和参数讲清楚。我做过几套类似的课设,血泪经验是:先把数据库跑通,再写一行 C# 代码,顺序反了会浪费大量时间在排查连接问题上。
2. 环境准备与 MySQL 数据库设计:先把地基打牢
2.1 MySQL 安装配置与建库建表的最小步骤
课设翻车最高频的场景是 MySQL 装完连不上。常见做法是下载 MySQL Community Server 的安装包,安装时勾选「MySQL Server」和「MySQL Workbench」,端口保持默认 3306,认证方式选Use Strong Password Encryption。安装完成后验证服务是否启动:
# Windows 下检查 MySQL 服务状态 sc query mysql80 # 如果服务未启动,手动启动 net start mysql80 # 登录验证,-u 用户名 -p 表示密码交互输入 mysql -u root -p登录成功后创建数据库和专用用户。不要直接用 root 跑应用,这是习惯问题:
-- 创建数据库,字符集用 utf8mb4 支持中文和特殊符号 CREATE DATABASE house_rental DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_general_ci; -- 创建应用专用用户,% 表示允许任意主机连接(课设本机可用 localhost) CREATE USER 'rental_app'@'localhost' IDENTIFIED BY 'Rental@2024'; -- 授予该库的全部权限 GRANT ALL PRIVILEGES ON house_rental.* TO 'rental_app'@'localhost'; FLUSH PRIVILEGES;参数说明:utf8mb4而不是utf8,因为 MySQL 的utf8是三个字节,存不了 emoji 和部分生僻字;utf8mb4_general_ci是大小写不敏感的排序规则,适合课设场景。FLUSH PRIVILEGES让权限立即生效,少了这行有时会遇到「明明授权了却连不上」的玄学问题。
2.2 房屋租赁系统的表结构设计与字段约束
房屋租赁管理系统的核心实体有四张主表:房东表、租客表、房源表、合同表。设计时要把外键和业务约束想清楚,否则后面写 C# 代码时会发现数据对不上。
| 表名 | 关键字段 | 约束说明 |
|---|---|---|
| landlord | id, name, phone, id_card | phone 唯一,id_card 唯一 |
| tenant | id, name, phone, id_card | phone 唯一 |
| house | id, landlord_id, address, area, rent, status | landlord_id 外键,status 枚举 |
| contract | id, house_id, tenant_id, start_date, end_date, deposit | 两个外键,日期区间校验 |
建表语句示例,以房源表为例:
CREATE TABLE house ( id INT PRIMARY KEY AUTO_INCREMENT, landlord_id INT NOT NULL, address VARCHAR(200) NOT NULL, area DECIMAL(8,2) NOT NULL COMMENT '面积,平方米', rent DECIMAL(10,2) NOT NULL COMMENT '月租金', status TINYINT DEFAULT 0 COMMENT '0待租 1已租 2下架', created_at DATETIME DEFAULT CURRENT_TIMESTAMP, CONSTRAINT fk_house_landlord FOREIGN KEY (landlord_id) REFERENCES landlord(id) ON DELETE RESTRICT ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;逻辑说明:status用 TINYINT 而不是字符串,查询效率高且省空间;ON DELETE RESTRICT表示房东还有房源时不允许删除,这是业务约束,比在代码里判断更可靠。DECIMAL(10,2)存金额,绝不能用 FLOAT,浮点误差在租金计算里会出问题。合同表的日期区间校验建议用触发器或应用层校验,MySQL 8.0 支持 CHECK 约束但兼容性一般,课设里用 C# 端校验更稳妥。
3. C# 连接 MySQL 与数据访问层实现
3.1 用 MySqlConnector 建立连接与连接池配置
C# 连 MySQL 有两个主流驱动:Oracle 官方的MySql.Data和社区维护的MySqlConnector。课设里我一般推荐MySqlConnector,因为它对异步支持更好、连接池行为更可预测,而且没有官方驱动那些历史包袱。通过 NuGet 安装:
# 在项目目录下执行,或通过 Visual Studio 的 NuGet 包管理器 dotnet add package MySqlConnector --version 2.3.5连接字符串的写法直接决定性能和稳定性:
// App.config 或代码中构造连接字符串 string connStr = "Server=localhost;Port=3306;Database=house_rental;" + "User Id=rental_app;Password=Rental@2024;" + "Pooling=true;MinimumPoolSize=5;MaximumPoolSize=50;" + "ConnectionTimeout=10;DefaultCommandTimeout=30;"; // 使用 using 确保连接归还到池 using var conn = new MySqlConnection(connStr); conn.Open();参数说明:Pooling=true开启连接池,这是默认值但显式写出更清晰;MinimumPoolSize=5保持 5 个常驻连接,避免每次请求都新建;MaximumPoolSize=50是课设场景的合理上限,太大反而会拖垮本机 MySQL;ConnectionTimeout=10表示 10 秒连不上就抛异常,不要设太大,否则界面会卡死。using语句保证连接对象释放后归还池中,不是真正关闭 TCP 连接。
3.2 封装通用的增删改查方法
课设里最容易写乱的是数据访问代码,每个功能都复制一遍连接、命令、读取。正确做法是抽一个DbHelper类,把参数化查询封装好。参数化是防 SQL 注入的关键,也是热词里「数据库增删改查」真正该关注的点:
public static int ExecuteNonQuery(string sql, params MySqlParameter[] parameters) { using var conn = new MySqlConnection(connStr); using var cmd = new MySqlCommand(sql, conn); if (parameters != null) cmd.Parameters.AddRange(parameters); conn.Open(); return cmd.ExecuteNonQuery(); // 返回受影响行数 } public static DataTable ExecuteQuery(string sql, params MySqlParameter[] parameters) { using var conn = new MySqlConnection(connStr); using var cmd = new MySqlCommand(sql, conn); if (parameters != null) cmd.Parameters.AddRange(parameters); using var adapter = new MySqlDataAdapter(cmd); var dt = new DataTable(); adapter.Fill(dt); return dt; }逻辑说明:ExecuteNonQuery用于 INSERT、UPDATE、DELETE,返回受影响行数,调用方据此判断是否成功;ExecuteQuery返回DataTable,适合课设里直接绑定 DataGridView。参数用MySqlParameter[]传入,调用时这样写:
string sql = "INSERT INTO tenant(name, phone, id_card) VALUES(@name, @phone, @idCard)"; var rows = DbHelper.ExecuteNonQuery(sql, new MySqlParameter("@name", "张三"), new MySqlParameter("@phone", "13800138000"), new MySqlParameter("@idCard", "110101199001011234")); if (rows > 0) MessageBox.Show("添加成功");注意:参数名前的@不能省,MySqlParameter会自动处理类型转义。不要用字符串拼接 SQL,"WHERE name='" + name + "'"这种写法遇到单引号就崩,也是注入漏洞的源头。
4. 房屋租赁核心业务功能的落地实现
4.1 房源状态流转与合同签订的联动逻辑
房屋租赁系统区别于普通 CRUD 的地方在于状态流转:房源从「待租」到「已租」,合同从「生效」到「到期」。这个联动必须放在事务里,否则会出现「合同签了但房源还是待租」的脏数据。用MySqlTransaction保证原子性:
using var conn = new MySqlConnection(connStr); conn.Open(); using var tx = conn.BeginTransaction(); try { // 第一步:插入合同 string sql1 = "INSERT INTO contract(house_id, tenant_id, start_date, end_date, deposit) " + "VALUES(@hid, @tid, @start, @end, @deposit)"; using var cmd1 = new MySqlCommand(sql1, conn, tx); cmd1.Parameters.AddWithValue("@hid", houseId); cmd1.Parameters.AddWithValue("@tid", tenantId); cmd1.Parameters.AddWithValue("@start", startDate); cmd1.Parameters.AddWithValue("@end", endDate); cmd1.Parameters.AddWithValue("@deposit", deposit); cmd1.ExecuteNonQuery(); // 第二步:更新房源状态为已租 string sql2 = "UPDATE house SET status=1 WHERE id=@hid AND status=0"; using var cmd2 = new MySqlCommand(sql2, conn, tx); cmd2.Parameters.AddWithValue("@hid", houseId); int affected = cmd2.ExecuteNonQuery(); if (affected == 0) throw new Exception("房源已被租出,请刷新后重试"); tx.Commit(); } catch (Exception ex) { tx.Rollback(); MessageBox.Show("签约失败:" + ex.Message); }逻辑说明:UPDATE ... WHERE status=0这个条件很关键,它做了乐观锁——如果房源已被别人租走,受影响行数为 0,直接抛异常回滚。这样并发场景下不会出现一房两租。BeginTransaction默认隔离级别是RepeatableRead,课设场景够用。参数用AddWithValue更简洁,但要注意日期类型传DateTime而不是字符串。
4.2 租金到期提醒与查询统计的 SQL 写法
课设答辩常被问「你怎么查到期的合同」。用DATEDIFF计算剩余天数,配合 C# 端定时查询:
-- 查询 30 天内到期的合同,关联出租客和房源信息 SELECT c.id, t.name AS tenant_name, h.address, c.end_date, DATEDIFF(c.end_date, CURDATE()) AS days_left FROM contract c JOIN tenant t ON c.tenant_id = t.id JOIN house h ON c.house_id = h.id WHERE c.end_date BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 30 DAY) ORDER BY days_left ASC;参数说明:DATEDIFF(end_date, CURDATE())返回天数差,正数表示还没到期;BETWEEN ... AND ...包含边界;INTERVAL 30 DAY是 MySQL 的日期运算语法。C# 端用ExecuteQuery拿到 DataTable 后绑定到提醒列表即可。统计类查询比如「每个房东名下有几套房」,用GROUP BY加COUNT:
SELECT l.name, COUNT(h.id) AS house_count FROM landlord l LEFT JOIN house h ON l.id = h.landlord_id GROUP BY l.id, l.name HAVING house_count > 0;用LEFT JOIN保证没有房源的房东也出现(虽然 HAVING 过滤掉了),理解 JOIN 的方向是课设里区分水平的地方。
5. 课设落地避坑:连接、编码、事务的常见翻车现场
5.1 连接失败与认证插件不兼容
现象:C# 程序报Authentication method 'caching_sha2_password' not supported。原因:MySQL 8.0 默认认证插件是caching_sha2_password,老版本MySql.Data驱动不支持。解决:要么升级驱动到 8.0 以上,要么改用户认证方式:
ALTER USER 'rental_app'@'localhost' IDENTIFIED WITH mysql_native_password BY 'Rental@2024'; FLUSH PRIVILEGES;我一般优先升级驱动,改认证方式是退路。
5.2 中文乱码:从建库到连接字符串的完整链路
现象:插入的中文变成???或乱码。原因:字符集在某一层没对齐。解决:建库用utf8mb4,表用utf8mb4,连接字符串加Character Set=utf8mb4,C# 源文件保存为 UTF-8。四层缺一不可。检查当前字符集:
SHOW VARIABLES LIKE 'character_set%';如果character_set_server不是utf8mb4,改 MySQL 配置文件my.ini的[mysqld]段加character-set-server=utf8mb4,重启服务。
5.3 连接池耗尽与连接未释放
现象:程序跑一会儿报Timeout expired... max pool size reached。原因:连接对象没释放,池里连接被占满。解决:所有MySqlConnection必须用using包裹,DataReader也要及时关闭。用using声明后,即使抛异常也会释放。检查是否有遗漏:
// 错误写法:conn 没有 using,异常时不会释放 var conn = new MySqlConnection(connStr); conn.Open(); // ... 中间抛异常,conn 泄漏 // 正确写法 using var conn = new MySqlConnection(connStr);5.4 外键约束导致的删除失败
现象:删除房东时报Cannot delete or update a parent row。原因:该房东名下还有房源,外键ON DELETE RESTRICT阻止删除。解决:先删房源或改外键为ON DELETE CASCADE。课设里建议保留 RESTRICT,在 C# 端先查再提示用户,比级联删除更安全,避免误删数据。
5.5 日期格式与参数类型不匹配
现象:插入日期报Incorrect datetime value。原因:C# 的DateTime直接AddWithValue一般没问题,但如果传的是字符串"2024/01/01",MySQL 可能不认。解决:统一用DateTime类型传参,或在 SQL 里用STR_TO_DATE转换。我习惯在 C# 端就转好类型,SQL 里不做格式转换。
6. 从课设到可演示系统:设计报告与答辩加分技巧
课设不只是代码能跑,设计报告和演示效果占分很重。报告里的 E-R 图用 Visio 或 draw.io 画,把四张表的联系标清楚:房东与房源是一对多,房源与合同是一对一(有效期内),租客与合同是一对多。表结构用表格列出字段、类型、约束、说明,比截图更专业。
演示时准备三条数据链路:新增房东 → 新增房源 → 签约合同,这条链路能展示外键和事务;查询到期合同展示 JOIN 和日期函数;删除有房源的房东展示约束保护。每条链路提前跑一遍,确保没有脏数据。
一个具体技巧:在 C# 里加一个「一键初始化数据库」按钮,读取 SQL 脚本文件执行建库建表。这样答辩换电脑时不用手动敲命令,也避免现场环境问题翻车。代码大致是读文件、按分号拆分、逐条执行,注意跳过注释行。
string script = File.ReadAllText("init.sql"); var statements = script.Split(';', StringSplitOptions.RemoveEmptyEntries); foreach (var stmt in statements) { if (string.IsNullOrWhiteSpace(stmt) || stmt.TrimStart().StartsWith("--")) continue; DbHelper.ExecuteNonQuery(stmt); }这个习惯我保持到现在:任何需要演示的项目,都准备一个幂等的初始化入口。课设的价值不在于功能多复杂,而在于你能不能把「数据从哪来、到哪去、约束在哪」讲明白。把连接池、事务、字符集这三件事吃透,比堆十个花哨功能更能打动答辩老师。希望帮到你。
本文还有配套的精品资源,点击获取