
简介这份资源是面向计算机相关专业在校学生与教师的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_applocalhost IDENTIFIED BY Rental2024; -- 授予该库的全部权限 GRANT ALL PRIVILEGES ON house_rental.* TO rental_applocalhost; FLUSH PRIVILEGES;参数说明utf8mb4而不是utf8因为 MySQL 的utf8是三个字节存不了 emoji 和部分生僻字utf8mb4_general_ci是大小写不敏感的排序规则适合课设场景。FLUSH PRIVILEGES让权限立即生效少了这行有时会遇到「明明授权了却连不上」的玄学问题。2.2 房屋租赁系统的表结构设计与字段约束房屋租赁管理系统的核心实体有四张主表房东表、租客表、房源表、合同表。设计时要把外键和业务约束想清楚否则后面写 C# 代码时会发现数据对不上。表名关键字段约束说明landlordid, name, phone, id_cardphone 唯一id_card 唯一tenantid, name, phone, id_cardphone 唯一houseid, landlord_id, address, area, rent, statuslandlord_id 外键status 枚举contractid, 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 ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;逻辑说明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 Serverlocalhost;Port3306;Databasehouse_rental; User Idrental_app;PasswordRental2024; Poolingtrue;MinimumPoolSize5;MaximumPoolSize50; ConnectionTimeout10;DefaultCommandTimeout30;; // 使用 using 确保连接归还到池 using var conn new MySqlConnection(connStr); conn.Open();参数说明Poolingtrue开启连接池这是默认值但显式写出更清晰MinimumPoolSize5保持 5 个常驻连接避免每次请求都新建MaximumPoolSize50是课设场景的合理上限太大反而会拖垮本机 MySQLConnectionTimeout10表示 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会自动处理类型转义。不要用字符串拼接 SQLWHERE 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 status1 WHERE idhid AND status0; 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 status0这个条件很关键它做了乐观锁——如果房源已被别人租走受影响行数为 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加COUNTSELECT 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_applocalhost IDENTIFIED WITH mysql_native_password BY Rental2024; FLUSH PRIVILEGES;我一般优先升级驱动改认证方式是退路。5.2 中文乱码从建库到连接字符串的完整链路现象插入的中文变成???或乱码。原因字符集在某一层没对齐。解决建库用utf8mb4表用utf8mb4连接字符串加Character Setutf8mb4C# 源文件保存为 UTF-8。四层缺一不可。检查当前字符集SHOW VARIABLES LIKE character_set%;如果character_set_server不是utf8mb4改 MySQL 配置文件my.ini的[mysqld]段加character-set-serverutf8mb4重启服务。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/01MySQL 可能不认。解决统一用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); }这个习惯我保持到现在任何需要演示的项目都准备一个幂等的初始化入口。课设的价值不在于功能多复杂而在于你能不能把「数据从哪来、到哪去、约束在哪」讲明白。把连接池、事务、字符集这三件事吃透比堆十个花哨功能更能打动答辩老师。希望帮到你。本文还有配套的精品资源点击获取