尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

MySQL与C#实战:房屋租赁管理系统数据库课程设计全流程解析

发布时间:2026/9/26 0:26:05

资讯中心
01
ARTICLE

MySQL与C#实战:房屋租赁管理系统数据库课程设计全流程解析

MySQL与C#实战:房屋租赁管理系统数据库课程设计全流程解析
简介一份面向高校数据库课程设计与毕业设计的房屋租赁管理系统完整源码包基于C#与MySQL实现适合正在完成管理信息系统类课题的学生作为参考。系统涵盖房屋信息、租客合同、费用结算等常见业务模块可帮助理解C# WinForms界面开发与MySQL数据库联动的基本流程。压缩包共71个文件大小约12.84MB包含25个C#源码文件、项目解决方案与配置文件、数据库初始化脚本、可执行程序、界面资源文件以及设计文档另有ER图与数据流图可用于辅助理解数据库设计与系统架构。目前已有415人学习下载。通过这份资料读者可以获得完整的系统源码、数据库建表脚本、课程设计报告和配套说明文档便于对照运行演示、梳理代码逻辑并在此基础上进行功能扩展或改造适合作为课程设计报告撰写和答辩准备的参考资料。1. 房屋租赁管理系统这个课设题为什么总被数据库课程选作压轴题数据库课程设计走到最后十个组里有三四个都在做房屋租赁管理系统这不是巧合。房源、租客、合同、缴费、退租每一类数据之间都有清晰的主外键关系天然就是一张好画的ER图而“有空房→登记租客→签合同→收租→退租结算”这条链路又恰好能把增删改查、事务、存储过程、报表这些数据库课设必须覆盖的点全部串起来。对要拿C#和MySQL交作业的同学来说这套系统工作量适中、业务逻辑好讲、答辩时老师爱问的问题也有标准答案。这篇笔记从建库讲到连库再讲到业务层和相处半学期的各种坑照着做就能把课设从“跑不起来”推进到“能演示、能答辩”。2. 先把MySQL底子打好房屋租赁的表设计与初始化脚本2.1 别急着写代码先画清楚这五张核心表很多同学拿到课程设计.zip之后第一反应是解压、双击.sln、点启动结果MySQL服务没开、数据库没导入、连接字符串写错界面刚弹出来就报异常。我的习惯是反着来先把数据库想清楚再回头写C#。房屋租赁管理系统无论界面做得多花哨最终要落地的就五张表。第一张是房屋表核心字段是房屋编号、地址、面积、户型、月租金、押金、状态。状态字段建议用TINYINT0表示空闲、1表示已出租不要用字符串“空闲”“已租”字符串存在数据库里占空间写错一个字就匹配不上。第二张是租客表身份证号一定要设UNIQUE这是业务上的天然约束不设的话同一个身份信息能在两台电脑录进两条记录答辩时老师一问就露馅。第三张是合同表它是整个系统的枢纽外键指向房屋和租客。合同表里除了起止日期、月租、押金最好再加一个“状态”字段表示执行中、已退租、已到期后续所有统计都靠这个字段过滤。第四张是缴费表记录每一笔租金和押金的收付字段包括金额、类型、日期、对应合同。第五张是管理员表只有账号和密码两列登录模块用。提示课设里最常见的改表方式不是因为需求复杂而是前期少画了一个字段后期在代码里用字符串拼接去“补逻辑”。所以画表时请把租赁业务从头走一遍至少把“合同终止后押金退不退、水电费怎么算”这两个问题想清楚再建表。2.2 建库脚本从ER图到可执行的MySQL DDL画完ER图就可以写DDL了不要用Navicat或MySQL Workbench的图形界面一张一张建。图形界面建表虽然快但建完无法在答辩时快速讲清楚约束关系而且如果是MySQL 8.0版本图形工具生成的外键命名规则看着就头疼。把脚本存成init.sql在MySQL命令行里一次性执行这才是课设该有的交付物。CREATE DATABASE IF NOT EXISTS house_rental DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_general_ci; USE house_rental; CREATE TABLE admin ( admin_id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) NOT NULL UNIQUE, password VARCHAR(64) NOT NULL ) ENGINEInnoDB; CREATE TABLE house ( house_id INT AUTO_INCREMENT PRIMARY KEY, house_no VARCHAR(20) NOT NULL UNIQUE COMMENT 房源编号如A-101, address VARCHAR(100) NOT NULL, area DECIMAL(6,2) NOT NULL COMMENT 面积单位平方米, house_type VARCHAR(20) COMMENT 户型如两室一厅, monthly_rent DECIMAL(8,2) NOT NULL, deposit DECIMAL(8,2) NOT NULL, status TINYINT NOT NULL DEFAULT 0 COMMENT 0空闲 1出租, created_at DATETIME DEFAULT CURRENT_TIMESTAMP ) ENGINEInnoDB;房屋表是业务起点SQL里要注意的三处一是DECIMAL不要用FLOAT租金这种精确数值用FLOAT会出现二进制舍入误差打印账单时差一分钱没法解释二是house_no设了UNIQUE同一个小区的房号不可能重复这是数据库替你守住的数据完整性三是ENGINE必须指定InnoDB只有InnoDB支持外键和事务MyISAM没法建外键退租结算这种多表操作没有事务就等着账目错乱。CREATE TABLE tenant ( tenant_id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(30) NOT NULL, id_card CHAR(18) NOT NULL UNIQUE COMMENT 身份证号固定18位, phone VARCHAR(20) NOT NULL, emergency_contact VARCHAR(30), emergency_phone VARCHAR(20), register_time DATETIME DEFAULT CURRENT_TIMESTAMP ) ENGINEInnoDB; CREATE TABLE rental_contract ( contract_id INT AUTO_INCREMENT PRIMARY KEY, contract_no VARCHAR(30) NOT NULL UNIQUE COMMENT 合同编号如HT20250101, house_id INT NOT NULL, tenant_id INT NOT NULL, start_date DATE NOT NULL, end_date DATE NOT NULL, monthly_rent DECIMAL(8,2) NOT NULL, deposit_paid DECIMAL(8,2) NOT NULL DEFAULT 0, status TINYINT NOT NULL DEFAULT 1 COMMENT 1执行中 2已退租 3已到期, CONSTRAINT fk_contract_house FOREIGN KEY (house_id) REFERENCES house(house_id), CONSTRAINT fk_contract_tenant FOREIGN KEY (tenant_id) REFERENCES tenant(tenant_id), INDEX idx_contract_status (status) ) ENGINEInnoDB; CREATE TABLE payment ( payment_id INT AUTO_INCREMENT PRIMARY KEY, contract_id INT NOT NULL, pay_type TINYINT NOT NULL COMMENT 1租金 2押金 3水电费, amount DECIMAL(8,2) NOT NULL, pay_date DATETIME DEFAULT CURRENT_TIMESTAMP, remark VARCHAR(100), CONSTRAINT fk_payment_contract FOREIGN KEY (contract_id) REFERENCES rental_contract(contract_id) ) ENGINEInnoDB;合同表和缴费表是“一主多子”的关系一张合同对应多笔缴费记录。写外键时我建议给约束起名字比如fk_contract_house因为MySQL默认生成的约束名是表名加随机后缀后期要删约束时比对着字段名猜还费劲。id_card设成CHAR(18)而不是VARCHAR(20)能同时约束长度和存储方式答辩时被问到“身份证号为什么不用VARCHAR”能答出这个点印象分直接拉满。2.3 初始化数据与演示账号让课设答辩不卡壳表建完必须导数据。我见过太多课设系统登录进去房源列表都是空的老师问“这个房源能不能租”只能当场现填表单填完又因为日期格式不对报错整段演示全在翻车。预置数据的核心目的不是省事而是让演示路径可控——你先知道列表里有什么房子才能预设“把A-101租给张三”这条演示线索。INSERT INTO admin (username, password) VALUES (admin, MD5(123456)); INSERT INTO house (house_no, address, area, house_type, monthly_rent, deposit, status) VALUES (A-101, 阳光花园1栋1单元101室, 89.50, 两室一厅, 2200.00, 2200.00, 0), (A-102, 阳光花园1栋1单元102室, 89.50, 两室一厅, 2200.00, 2200.00, 0), (B-201, 阳光花园2栋2单元201室, 65.00, 一室一厅, 1600.00, 1600.00, 0);密码用MD5加密是一般做法但MD5本身不是安全的加密算法这里是为了对齐课程里“密码不能明文存”的考点才这么写。如果你愿意多花半小时可以在C#里用SHA256加盐代替答辩时还能主动讲一句“我了解MD5碰撞的问题所以用了更稳妥的做法”——这句话对拿高分非常有效。房源数建议至少插入10条覆盖不同户型、不同租金区间做查询功能时才有的查统计报表时图表才不空。注意MySQL 8.0里MD5()函数仍然可用但如果在初始化脚本里写INSERT执行完最好自查一遍用SELECT * FROM admin确认结果因为某些图形客户端执行脚本时会把SQL语句里的中文注释转成乱码。遇到这种情况把脚本文件另存为UTF-8无BOM格式再重新执行。3. C# 连接 MySQL从连接字符串到三层结构的第一个窗口3.1 选WinForm还是WPF课设场景下的取舍C#做桌面端有两种主流选择WinForm和WPF历届学生里选WinForm的占大多数。原因是它的控件足够老旧也足够成熟DataGridView两行代码就能绑定一张表ComboBox下拉框拖上去就能用对只要求“完成增删改查”的课程设计来说开发效率极高。WPF的数据绑定需要理解DependencyProperty和INotifyPropertyChanged学习曲线两个月起步不适合两周交稿的课设。但WinForm有一个先天毛病高分屏下控件缩放模糊答辩投影仪上一片虚影。解决办法是在Main方法入口调用SetProcessDPIAware或者把项目清单里的DPI设置改成PerMonitorV2。你不需要理解GDI内部原理只要知道这是WinForm在高分屏下的已知问题加几行调用代码就能让字体清晰很多。这是课设里少有的“不增加任何功能却能让演示观感质变”的玄学操作值得做。另一个取舍是.NET Framework还是.NET 6/8。如果电脑上装的是Visual Studio 2022新建项目时默认是.NET 8但很多课设模板和老师给的范例都是.NET Framework 4.7.2。我建议跟着你电脑里已经能跑通的模板走不要为了追新版本单独配环境课设评审看的是业务完整性不是运行时版本。MySQL连接库用的是MySql.DataConnector/NET无论哪个框架版本用NuGet安装的方式完全一致。3.2 DbHelper一个能扛住课设全部功能的数据库访问基类不管界面是登录、房源列表还是缴费流水所有窗口访问数据库的方式都相同拼SQL、拿连接、执行、关连接。如果不做封装每个页面都会重复写一遍连接开关、命令参数赋值、异常处理到后期一处改动全盘重改。所以开局建一个DbHelper基类后面所有窗体都调用它是这个课设最值得花时间的一件事。using System; using System.Data; using MySql.Data.MySqlClient; public class DbHelper { public static readonly string ConnStr Serverlocalhost;Port3306;Databasehouse_rental;Uidroot;Pwd123456; Charsetutf8mb4;SslModenone;AllowPublicKeyRetrievaltrue;; public static DataTable QueryToTable(string sql, params MySqlParameter[] parameters) { using (MySqlConnection conn new MySqlConnection(ConnStr)) { conn.Open(); using (MySqlCommand cmd new MySqlCommand(sql, conn)) { if (parameters ! null) cmd.Parameters.AddRange(parameters); MySqlDataAdapter adapter new MySqlDataAdapter(cmd); DataTable dt new DataTable(); adapter.Fill(dt); return dt; } } } public static int ExecuteNonQuery(string sql, params MySqlParameter[] parameters) { using (MySqlConnection conn new MySqlConnection(ConnStr)) { conn.Open(); using (MySqlCommand cmd new MySqlCommand(sql, conn)) { if (parameters ! null) cmd.Parameters.AddRange(parameters); return cmd.ExecuteNonQuery(); } } } }这个类解决两个问题一是连接生命周期using块保证连接用完后自动关闭不会出现连接池爆满二是参数化params MySqlParameter[]允许上层任意传参数SQL里写name、pwd之类的占位符值通过参数传入永远不拼字符串。关于SslModenone和AllowPublicKeyRetrievaltrue这两个参数是MySQL 8.0本地开发最常见的组合前者关闭SSL校验避免本地证书问题后者允许客户端自动获取服务器公钥缺了它会在认证握手阶段直接抛异常。3.3 登录模块第一道门要能过编译更要能过答辩登录是每个评委都会亲手点一遍的入口。这里不要直接用SQL拼where usernametextbox.Text这是所有安全相关提问的靶子。用参数化查询把用户名和密码都作为参数传入同时密码要与初始化脚本里的MD5算法对应代码里对输入框再做一次哈希再比对。private void btnLogin_Click(object sender, EventArgs e) { if (string.IsNullOrWhiteSpace(txtUser.Text) || string.IsNullOrWhiteSpace(txtPwd.Text)) { MessageBox.Show(用户名和密码不能为空); return; } string hashed Md5Helper.Hash(txtPwd.Text.Trim()); string sql SELECT admin_id FROM admin WHERE usernameu AND passwordp; DataTable dt DbHelper.QueryToTable(sql, new MySqlParameter(u, txtUser.Text.Trim()), new MySqlParameter(p, hashed)); if (dt.Rows.Count 1) { this.Hide(); MainForm main new MainForm(); main.Show(); } else { MessageBox.Show(用户名或密码错误); txtPwd.Clear(); txtPwd.Focus(); } }这段代码里两个容易被忽略的细节一是空白输入要拦在校验之前不然空密码的MD5值也会去数据库比对一次虽然查不到结果但浪费一次连接二是登录失败后只清空密码框、保留用户名让用户少敲几个字。Md5Helper这个工具类写起来很简单用System.Security.Cryptography的MD5.Create对输入字符串的UTF-8字节流计算哈希再转成小写十六进制字符串和MySQL端MD5()生成的结果一致。答辩时老师通常会问“密码为什么是32位的一串字母数字”顺着这个点把MD5哈希讲清楚顺便提一句“实际生产环境会用加盐哈希”这段对话就是你的加分环节。4. 把租赁业务跑通房屋管理、租客登记与退租结算4.1 房屋列表与状态联动一个下拉框是怎么绑定数据库的房屋管理页面在课设里通常是“用DataGridView做增删改查”的展示点。这里最容易出现的失误是把所有查询逻辑都塞在同一个方法里导致页面加载时执行一次、点按钮时又执行一次。正确的做法是写一个RefreshHouseList()方法内部调用DbHelper查询当前页面的列表数据页面Load、ComboBox切换、增删操作完成后都调用同一个方法保证所有入口的数据一致。private void RefreshHouseList() { string sql SELECT house_id, house_no, address, area, house_type, monthly_rent, deposit, CASE status WHEN 0 THEN 空闲 WHEN 1 THEN 已出租 END AS status_text FROM house ORDER BY house_no; DataTable dt DbHelper.QueryToTable(sql); dgvHouse.DataSource dt; // 状态筛选下拉框ValueMember为数据库状态值DisplayMember为界面显示文本 DataTable statusTable new DataTable(); statusTable.Columns.Add(status, typeof(int)); statusTable.Columns.Add(text, typeof(string)); statusTable.Rows.Add(0, 空闲); statusTable.Rows.Add(1, 已出租); cmbFilter.DataSource statusTable; cmbFilter.ValueMember status; cmbFilter.DisplayMember text; }DataGridView绑定DataTable之后列头默认会显示数据库字段名比如house_no、monthly_rent很生硬。可以在表设计器里把这两列改成“房号”“月租金”也可以在SQL里用别名直接改。我个人推荐SQL别名方案因为查询结果统一由SQL层控制改起来不用动窗体设计器。状态字段在数据库里是0和1界面上要显示“空闲/已出租”这里用了CASE WHEN把整数翻译成文字比在C#代码里循环遍历DataTable去转换要简单一行SQL就解决了。注意不能直接用cmbFilter.SelectedValue拿状态值再拼WHERE条件“SELECT * FROM house WHERE status cmbFilter.SelectedValue这种写法会出现两个问题——SelectedValue可能为null导致SQL多出一个“ ”语法错误同时它把用户输入拼进SQL违背了前面DbHelper封装参数化的初衷。正确写法是把SelectedValue先Convert.ToInt32转成int变量再作为MySqlParameter传入。4.2 签订合同用事务把一次签约拆成三步房屋从“空闲”变“已出租”不是改一个状态位就行而是要同时完成三件事插入合同记录、写入一笔押金缴费记录、把房屋表状态改成1。这三步中的任何一步失败数据库都会处于“合同建了但房子还是空闲”或“房子已出租但没有合同”的矛盾状态。单条UPDATE或INSERT不会出问题但三步合起来必须用事务包裹。public bool SignContract(int houseId, int tenantId, DateTime startDate, DateTime endDate, decimal monthlyRent, decimal deposit) { string contractNo HT DateTime.Now.ToString(yyyyMMddHHmmss); string sqlInsert INSERT INTO rental_contract (contract_no, house_id, tenant_id, start_date, end_date, monthly_rent, deposit_paid, status) VALUES (contractNo, houseId, tenantId, startDate, endDate, monthlyRent, deposit, 1); string sqlPayment INSERT INTO payment (contract_id, pay_type, amount, remark) VALUES (contractId, 2, deposit, 签约押金); string sqlUpdateHouse UPDATE house SET status1 WHERE house_idhouseId AND status0; using (MySqlConnection conn new MySqlConnection(DbHelper.ConnStr)) { conn.Open(); using (MySqlTransaction trans conn.BeginTransaction()) { try { // 第一步插入合同并获得自增ID long contractId; using (MySqlCommand cmd1 new MySqlCommand(sqlInsert, conn, trans)) { cmd1.Parameters.Add(new MySqlParameter(contractNo, contractNo)); cmd1.Parameters.Add(new MySqlParameter(houseId, houseId)); cmd1.Parameters.Add(new MySqlParameter(tenantId, tenantId)); cmd1.Parameters.Add(new MySqlParameter(startDate, startDate)); cmd1.Parameters.Add(new MySqlParameter(endDate, endDate)); cmd1.Parameters.Add(new MySqlParameter(monthlyRent, monthlyRent)); cmd1.Parameters.Add(new MySqlParameter(deposit, deposit)); cmd1.ExecuteNonQuery(); contractId cmd1.LastInsertedId; } // 第二步写入押金流水 using (MySqlCommand cmd2 new MySqlCommand(sqlPayment, conn, trans)) { cmd2.Parameters.Add(new MySqlParameter(contractId, contractId)); cmd2.Parameters.Add(new MySqlParameter(deposit, deposit)); cmd2.ExecuteNonQuery(); } // 第三步把房屋改为已出租加AND status0防止重复签约 using (MySqlCommand cmd3 new MySqlCommand(sqlUpdateHouse, conn, trans)) { cmd3.Parameters.Add(new MySqlParameter(houseId, houseId)); int affected cmd3.ExecuteNonQuery(); if (affected 0) throw new Exception(房屋可能已被他人签约请刷新后重试); } trans.Commit(); return true; } catch { trans.Rollback(); throw; } } } }事务代码的要点是同一个连接必须传给所有Command对象和BeginTransaction的返回值cmd1、cmd2、cmd3这三个命令对象不能各自new一个MySqlConnection那样事务就不起作用了因为每个连接是独立会话。cmd1.LastInsertedId这个属性是MySql.Data库特有的执行完INSERT后自动拿到自增主键的值不需要再回查数据库。UPDATE house加AND status0这行很重要它用一行代码解决并发问题如果两个人同时签约同一间房先执行的人更新成功后执行的人影响行数为0直接抛异常比“先SELECT再UPDATE”的检查后执行逻辑安全得多。4.3 退租结算计算器、流水记录与坑点退租是课设业务链的最后一环也是最容易出逻辑漏洞的地方。退租行为同时包含把合同状态改成已退租、把房屋状态改回空闲、根据是否到期计算违约金或押金退还、把退还金额记录进缴费表。很多学生只做前两步押金退还完全不走数据库直接在界面上扣了个数字就完事答辩时老师让看流水这里一片空白整段业务逻辑就断了。private void btnDoReturn_Click(object sender, EventArgs e) { if (dgvContract.SelectedRows.Count 0) return; int contractId Convert.ToInt32(dgvContract.SelectedRows[0].Cells[contract_id].Value); int houseId Convert.ToInt32(dgvContract.SelectedRows[0].Cells[house_id].Value); decimal deposit Convert.ToDecimal(dgvContract.SelectedRows[0].Cells[deposit_paid].Value); DateTime endDate Convert.ToDateTime(dgvContract.SelectedRows[0].Cells[end_date].Value); bool overdue DateTime.Now.Date endDate.Date; // 逾期退租扣除全部押金作为违约金这是课设里的常见简化口径 decimal refund overdue ? 0m : deposit; string sql1 UPDATE rental_contract SET status2 WHERE contract_idcontractId AND status1; string sql2 UPDATE house SET status0 WHERE house_idhouseId; string sql3 INSERT INTO payment (contract_id, pay_type, amount, remark) VALUES (contractId, 2, refund, 退租退押金); using (MySqlConnection conn new MySqlConnection(DbHelper.ConnStr)) { conn.Open(); using (MySqlTransaction trans conn.BeginTransaction()) { try { using (MySqlCommand cmd1 new MySqlCommand(sql1, conn, trans)) { cmd1.Parameters.Add(new MySqlParameter(contractId, contractId)); cmd1.ExecuteNonQuery(); } using (MySqlCommand cmd2 new MySqlCommand(sql2, conn, trans)) { cmd2.Parameters.Add(new MySqlParameter(houseId, houseId)); cmd2.ExecuteNonQuery(); } using (MySqlCommand cmd3 new MySqlCommand(sql3, conn, trans)) { cmd3.Parameters.Add(new MySqlParameter(contractId, contractId)); cmd3.Parameters.Add(new MySqlParameter(refund, refund)); cmd3.ExecuteNonQuery(); } trans.Commit(); MessageBox.Show(退租结算完成退还押金 refund.ToString(F2)); } catch (Exception ex) { trans.Rollback(); MessageBox.Show(退租失败 ex.Message); } } } }退租逻辑里的两个坑值得单独说。第一是日期比较不能用“ endDate”草草了事DateTime.Now带时分秒而endDate是DATE类型凌晨零点到当天午夜之间必须用DateTime.Now.Date和endDate.Date做同量纲比较。第二是违约金的口径要在界面和说明文档里讲清楚——这里定义成“逾期一天即扣除全部押金”只是课设简化口径真实业务通常按天比例计算。你只要在代码注释和答辩PPT里把口径写明白老师不会纠结比例是否合理最怕的是代码里写了扣除、界面却不显示扣除明细前后对不上账。5. 课设避坑指南从连接失败到删除被拒的5个现场5.1 MySQL 8.0 连不上caching_sha2_password 引发的连锁反应现象代码里明明数据库名、账号、密码全是对的一运行就在DbHelper.QueryToTable里抛异常报错信息带“Authentication method caching_sha2_password not supported”或者“Unable to connect to any of the specified MySQL hosts”。原因MySQL 8.0默认把root用户的认证插件从mysql_native_password改成了caching_sha2_password而老版本的MySql.Data.dll连接器不认这个新插件双方握手失败。问题不在密码在认证协议。解决有两条路。第一条是在DbHelper的ConnStr里加SslModenone和AllowPublicKeyRetrievaltrue新版Connector/NET支持公钥检索后就能通过认证第二条是降级认证插件在MySQL命令行执行ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY 123456。课设场景推荐第一条因为不用动数据库用户配置只改代码里的连接字符串就行。5.2 中文全部变成问号utf8 和 utf8mb4 的差异不能靠运气现象C#界面里录入“张三”存进数据库或者从数据库读出来显示成了“???”。有时初始化脚本里明明写了DEFAULT CHARACTER SET utf8mb4插入的中文还是乱码。原因乱码链条有三个环节任何一个环节断了都乱——数据库和表的字符集、C#连接字符串的Charset参数、MySQL客户端导入脚本时的文件编码。最常见的断点在连接字符串Charsetutf8mb4写对了但表本身是utf8mb4两边不一致时连接层会做一次转码转完就丢了信息。解决三层全部对齐。建库脚本统一用utf8mb4连接字符串写Charsetutf8mb4同时确认NuGet里MySql.Data的版本在8.0.22以上。最后用SELECT直接查表内容验证一次不要只看界面显示正常就收工因为有些控件做了自动编码转换界面正常但库里存的是乱码答辩时打开表看数据就翻车。5.3 外键约束报错删除房屋时提示不能删除现象在房屋管理页面点删除一条房源记录直接弹“Cannot delete or update a parent row: a foreign key constraint fails”数据库没删成界面却弹了删除成功。原因这条房源已经被签过合同合同表里存在外键指向它。外键约束要求子表没有引用记录时父表才能执行DELETE否则MySQL拒绝删除。界面上“删除影响行数1”的提示没有与数据库异常挂钩异常被吞掉了。解决删房屋前先查合同表有合同记录的房源只做“逻辑删除”而不是物理删除。逻辑删除的做法是在house表加一个deleted字段删除操作变成UPDATE house SET deleted1没有合同引用的房源才走DELETE。这个点答辩时被问到的概率极高你把“保留历史合同、只做逻辑删除”这个理由讲出来比解释SQL错误强得多。5.4 日期时间到处飘DateTimePicker 默认值导致的隐藏 bug现象程序偶尔在“签合同”或“退租结算”时报参数异常或者在DataGridView里日期列显示“0001/1/1”存进去再读出来对不上。原因WinForm里DateTimePicker控件在正常情况下默认值是当前时间但如果页面加载时把Format设为Custom而没给Value赋初值某些初始化顺序下Value会变成DateTime.MinValue0001-01-01这个值超出MySQL DATE类型的合法范围1000-01-01起插入时直接被MySQL拒绝。解决在窗体构造函数里显式给所有DateTimePicker赋初值例如startDatePicker.Value DateTime.TodayendDatePicker.Value DateTime.Today.AddMonths(6)。另外约定所有从DataGridView取日期时用Convert.ToDateTime而不是直接强转Convert方法遇到DBNull会返回默认值而不是抛异常至少能让错误在界面层暴露而不是炸在SQL执行层。5.5 数据库文件拷不走课设验收前的最后一道坎现象把项目复制到另一台电脑上演示打开登录界面就报“Cant connect to MySQL server on localhost”检查服务开了、账号密码也没变还是连不上。原因你本机的MySQL服务虽然装了但另一台电脑上根本没有这个数据库实例和数据你拷走的只是代码和编译输出数据库还在旧机器的数据目录里待着。解决课设验收前做一个标准动作——导出完整SQL脚本。在Navicat或MySQL Workbench里选择“转储SQL文件”包含表结构、索引、外键和预置数据另存为init.sql和项目源码放在同一目录。换机器演示时先安装MySQL服务再导入init.sql数据库即恢复完整。目录结构建议做成CourseDesign_HouseRental里面放.sln、init.sql、READMEREADME里写清楚MySQL版本要求、连接字符串、默认管理员账号这份材料本身就是课设报告的一部分。6. 把课设从“能用”变成“加分”三处不改结构的小升级到这一步系统已经能跑通“登录—录房源—登记租客—签约—收租—退租”的完整链路但课设想拿高分还需要在答辩时让评委看到“结构之外的思考”。我建议从三处不动表结构的升级里选一个去做。第一处是给缴费统计加一个“本月应收”视图。用一条SQL把执行中合同的月租金汇总和当月实收流水作对比做成一个只读的DataGridView。这一步没有改任何表只是在列表页加了一个分组查询却能让老师看到你理解“数据从业务中来、再回到报表中去”这条主线。第二处是把状态筛选下拉框做成联动搜索按“空闲/已出租”筛选房源配合前面的CASE WHEN显示文字再给DataGridView加一个行背景色空闲的房源显示浅绿色已出租的显示浅灰色。颜色逻辑放在DataGridView的RowPostPaint事件里代码量不超过十行演示效果却很直观。第三处是写一个可以反复执行的“模拟月结”功能把当月租金批量生成缴费记录。这个点实现起来涉及循环和日期计算但业务路径非常清晰遍历所有status1的合同、把月租写入payment表、备注写“自动月结”。做出来后答辩时你可以现场演示“模拟两个月后”的报表老师往数据库里一看账目是完整的而不是只有登录页和空空的流水这套完整性演示在课设答辩里很能说服人。我的习惯是把这些升级都放在一个独立面板里叫“演示功能”和课设要求的CRUD页面分开这样评委能明确看出哪些是课程要求的、哪些是你主动做的扩展。希望帮到你。本文还有配套的精品资源点击获取
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。