当前位置: 首页 > news >正文

手把手教你用C# WinForms + ADO.NET实现学员信息管理(增删改)

一、项目概述

本程序实现了一个基于SQL Server数据库的学员信息管理工具,主要功能包括:

  • 添加学员:录入编号、姓名、性别、年龄

  • 修改学员:根据学员编号修改其性别和年龄

  • 删除学员:支持按姓名删除、按编号删除

界面使用WinForms设计,分为三个区域,如下图:

二、整体思路

拿到需求后,我的设计步骤如下:

  1. 数据库设计:创建stuInfo表,包含stuNo(学员编号,主键)、stuNamestuSexstuAge四个字段。

  2. 界面布局:用Panel分区,使用TextBox输入文本,ComboBox选择年龄(15-30岁),RadioButton选择性别。

  3. 数据操作:采用ADO.NET的SqlConnectionSqlCommand,编写SQL语句实现增删改。

  4. 异常处理与验证:对用户输入做非空校验,操作前先查询数据是否存在,避免直接操作失败。

三、准备工作

  • IDE:Visual Studio 2019/2022

  • .NET版本:.NET Framework 4.5+

  • 数据库:SQL Server 2012+(本例使用本地实例server=.

  • 数据库表脚本

CREATE DATABASE student; GO USE student; GO CREATE TABLE stuInfo ( stuNo NVARCHAR(20) PRIMARY KEY, stuName NVARCHAR(50) NOT NULL, stuSex NCHAR(1) CHECK(stuSex IN ('男','女')), stuAge INT CHECK(stuAge BETWEEN 15 AND 30) ); GO

四、核心代码解析

1. 窗体加载 – 初始化年龄下拉框

Form1_Load事件中,为两个年龄ComboBox动态添加15~30的数字。

private void Form1_Load(object sender, EventArgs e) { // 添加学员区的年龄下拉框 for (int i = 15; i <= 30; i++) { comboBox_age.Items.Add(i); } comboBox_age.SelectedIndex = 0; // 默认选中15 // 修改学员区的年龄下拉框 for (int i = 15; i <= 30; i++) { comboBox_exAge.Items.Add(i); } }

思路:固定范围选择避免了用户输入非法年龄。

2. 添加学员 – 完整业务流程

步骤

  • 非空校验(编号、姓名、性别)

  • 从控件取值,年龄需转为int

  • 连接数据库执行INSERT

  • 成功后清空表单

关键代码

private void button_add_Click(object sender, EventArgs e) { // 1. 非空判断 if (string.IsNullOrWhiteSpace(textBox_ID.Text)) { MessageBox.Show("请输入学员编号!"); return; } // ... 姓名、性别校验(性别必须二选一) string stuId = textBox_ID.Text; string stuName = textBox_name.Text; string stuSex = radioB_man.Checked ? "男" : "女"; int stuAge = Convert.ToInt32(comboBox_age.SelectedItem); // 2. 数据库插入 using (SqlConnection con = new SqlConnection(@"server=.;uid=sa;pwd=123;database=student")) { con.Open(); string sql = $"INSERT INTO stuInfo VALUES ('{stuId}','{stuName}','{stuSex}',{stuAge})"; using (SqlCommand cmd = new SqlCommand(sql, con)) { int result = cmd.ExecuteNonQuery(); if (result > 0) { MessageBox.Show("添加成功"); ClearAddForm(); // 自定义清空方法 } else MessageBox.Show("添加失败"); } } }

⚠️注意:代码中性别获取逻辑存在隐患 – 若两个RadioButton都未选中,会默认“女”。实际应该先判断,提示用户选择。我后来优化成了if-else结构。

3. 修改学员 – 先查后改

修改的核心思路:根据用户输入的编号,先查询数据库中是否存在该学员,若存在再执行UPDATE

private void button_exchange_Click(object sender, EventArgs e) { // 非空校验 if (string.IsNullOrWhiteSpace(textBox_exID.Text)) { MessageBox.Show("请输入要修改的学员编号!"); return; } string exstuID = textBox_exID.Text; using (SqlConnection con = new SqlConnection(connectionString)) { con.Open(); // 第一步:查是否存在 string checkSql = $"SELECT COUNT(*) FROM stuInfo WHERE stuNo='{exstuID}'"; using (SqlCommand checkCmd = new SqlCommand(checkSql, con)) { int count = (int)checkCmd.ExecuteScalar(); if (count == 0) { MessageBox.Show("查询不到此学员编号!"); return; } } // 第二步:获取新值(性别、年龄) string newSex = radioB_exMan.Checked ? "男" : "女"; int newAge = Convert.ToInt32(comboBox_exAge.SelectedItem); // 第三步:更新 string updateSql = $"UPDATE stuInfo SET stuSex='{newSex}', stuAge={newAge} WHERE stuNo='{exstuID}'"; using (SqlCommand cmd = new SqlCommand(updateSql, con)) { int result = cmd.ExecuteNonQuery(); if (result > 0) { MessageBox.Show("修改成功!"); ClearModifyForm(); } else MessageBox.Show("修改失败!"); } } }
4. 删除学员 – 按姓名 / 按编号

两个删除逻辑高度相似:校验非空 → 验证存在 → 执行DELETE。以按姓名删除为例:

private void button_delName_Click_1(object sender, EventArgs e) { if (string.IsNullOrWhiteSpace(textBox_delName.Text)) { MessageBox.Show("请输入要删除的姓名!"); return; } using (SqlConnection con = new SqlConnection(connectionString)) { con.Open(); // 验证姓名是否存在 string checkSql = $"SELECT COUNT(*) FROM stuInfo WHERE stuName='{textBox_delName.Text}'"; using (SqlCommand cmd = new SqlCommand(checkSql, con)) { int count = (int)cmd.ExecuteScalar(); if (count == 0) { MessageBox.Show("你输入的姓名不存在!"); return; } } // 执行删除(注意:会删除所有同名的记录!) string delSql = $"DELETE FROM stuInfo WHERE stuName='{textBox_delName.Text}'"; using (SqlCommand cmd = new SqlCommand(delSql, con)) { int count = cmd.ExecuteNonQuery(); if (count > 0) MessageBox.Show("删除成功!"); } } }

按编号删除代码类似,这里不再重复。

五、开发中遇到的问题 & 反思

🔴 问题1:SQL注入风险

整个项目中使用的是字符串拼接SQL,例如:

$"SELECT COUNT(*) FROM stuInfo WHERE stuNo='{exstuID}'"

如果用户在文本框输入' OR '1'='1,后果不堪设想。这是严重的安全隐患

解决方案:使用参数化查询。例如:

string sql = "INSERT INTO stuInfo VALUES (@no,@name,@sex,@age)"; SqlCommand cmd = new SqlCommand(sql, con); cmd.Parameters.AddWithValue("@no", stuId); // ... 其他参数
🔴 问题2:数据库连接字符串硬编码

代码中直接写死了server=.;uid=sa;pwd=123;database=student,一旦数据库密码或服务器变更,必须重新编译程序。

改进:将连接字符串写入App.config配置文件,通过ConfigurationManager读取。

🔴 问题3:控件事件绑定错误

设计文件中,button3被命名为“修改”按钮,却绑定了button_exchange_Click事件(这个事件是修改学员区的)。这是个明显的复制粘贴错误。

修正:删除button3或为其编写正确的删除逻辑。

🔴 问题4:删除后未清空输入框

添加/修改成功后清空了表单,但删除成功后没有清空对应的文本框,用户体验欠佳。

改进:在删除成功后调用textBox_delName.Clear()等。

🔴 问题5:年龄获取时的类型转换

代码中使用Convert.ToInt32(comboBox_age.SelectedItem),但如果用户未选择(SelectedItem为null),会抛出异常。虽然我初始化时设置了SelectedIndex=0,但严谨起见应该判断。

优化

if (comboBox_age.SelectedItem == null || !int.TryParse(comboBox_age.SelectedItem.ToString(), out int age)) { MessageBox.Show("请选择有效年龄!"); return; }
🔴 问题6:数据库连接未显式关闭

代码中多处写了con.Close(),但实际上using块结束时会自动释放并关闭连接,无需手动调用。手动调用也可能引发二次释放问题。

建议:去掉所有显式的Close(),依赖using即可。

六、总结

通过这个小项目,我们实践了WinForms的常用控件用法、ADO.NET的核心对象(Connection、Command、ExecuteNonQuery/ExecuteScalar)以及数据库的增删改基本操作。同时也暴露了代码中常见的几个坑:

  • 忘记校验性别是否选中

  • 忽略SQL注入风险

  • 事件绑定错乱

  • 资源管理可以更优雅

收获:以后写数据库交互代码,我会默认使用参数化查询+配置文件存储连接字符串+完善的输入验证。希望这篇博客也能让正在学习C#数据库编程的你少走一些弯路。

如果你有任何疑问或发现了其他bug,欢迎在评论区交流讨论!

http://www.jsqmd.com/news/760723/

相关文章:

  • 写了个小工具:PDF转PNG图片转换器插件
  • 避坑指南:onnx-simplifier安装失败?先检查你的onnx版本兼容性(附版本对照表)
  • Win10/Win11系统下,Solid Edge 2023安装激活保姆级避坑指南(附Crack文件处理全流程)
  • Docker Compose 如何限制容器内存和 CPU 资源部署配置
  • 无穿戴·无基站·无标签:2026无感定位技术,让室外数字孪生自主感知
  • 优先队列——延迟删除
  • OpenClaw用户如何通过Taotoken CLI快速写入配置并开始使用
  • World-To-Image算法:重构AIGC图像生成新范式
  • 使用Python通过Taotoken一键调用Claude与GPT模型
  • 【计算机网络】第10篇:距离矢量路由算法——Bellman-Ford方程与RIP协议的特性分析
  • R 4.5边缘AI上线倒计时:2024Q3起CRAN将强制要求静态链接声明——你还没适配R 4.5.0+新LinkingTo规范?
  • 26.人工智能实战:模型升级后线上效果反而变差?从 Prompt 回归测试到灰度发布的完整工程治理方案
  • 告别网络卡顿:用华为eNSP模拟真实办公网,实战QoS限速保障关键业务
  • 运行mysql
  • Video-Thinker-7B:视频理解与推理的开源模型解析
  • 江浙沪皖宣传栏定制厂家技术标准与落地指南 - 奔跑123
  • 3步快速实现AnyFlip电子书永久保存:终极免费下载指南
  • 2026年川渝滇陕附近工程机械维修厂家选择:工程机械维修电话、工程机械配件、成都工程机械维修、AGV叉车、内燃叉车选择指南 - 优质品牌商家
  • 教育领域AI情感分析技术解析与应用实践
  • 新手教程使用 Python 快速接入 Taotoken 并调用多模型完成对话
  • 2026北京豪华考斯特租车哪家靠谱:北京考斯特出租、北京考斯特包车、北京考斯特的商务车租赁、北京长期租车费用、带司机包车多少钱北京选择指南 - 优质品牌商家
  • AI代理安全新范式:BlindKey盲注机制与凭证管理实战
  • 【阿贝云】免费服务器使用感受(二)
  • 扩散模型强化学习优化:TreeGRPO算法解析与实践
  • SSRAM技术解析:高速缓存与存储系统的核心组件
  • AI生成多层级测试用例的工程实践与架构设计
  • 【计算机网络】第11篇:链路状态路由协议——Dijkstra算法与OSPF的分区架构
  • 如何用MaxBot抢票机器人轻松买到演唱会门票:2025年完整使用指南
  • CDL Practice Tests - AI
  • LangChain、LangGraph、Deep Agents傻傻分不清?一文彻底搞懂,AI开发者的进阶指南!