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

C#运动会成绩管理系统实战:SQL Server本地数据库部署与业务逻辑解析

发布时间:2026/9/26 7:18:24

资讯中心
01
ARTICLE

C#运动会成绩管理系统实战:SQL Server本地数据库部署与业务逻辑解析

C#运动会成绩管理系统实战:SQL Server本地数据库部署与业务逻辑解析
简介本资源是安徽工程大学数据库课程设计实践项目——运动会成绩管理系统面向高校计算机、信息管理类专业学生及数据库初学者解决校级体育赛事中项目、运动员与成绩的数字化管理需求。系统基于C#开发后端采用SQL Server数据库涵盖用户登录、成绩录入、预决赛名单生成、多维度统计查询等核心功能完整呈现课程设计从需求分析到系统实现的全流程。压缩包共72个文件含29个C#业务逻辑文件、12个资源文件.resx/.resources、1个SQL Server数据库文件.mdf/.ldf、1个Visual Studio解决方案.sln及详细使用说明文档.docx整体体积仅965KB结构清晰、开箱即用。已有1884人学习下载提供可直接运行的可执行程序.exe、完整源码、数据库脚本与界面设计文件特别适合课程设计参考、数据库应用开发入门与WinFormSQL Server综合实训。1. 这不是又一个“学生交差项目”安徽工程大学2020年真实落地的运动会成绩管理系统C# SQL Server双栈闭环VS2019开箱即跑含完整数据库文件.mdf/.ldf与可执行界面逻辑你肯定见过太多标着“课程设计”的压缩包——点开全是空窗体、没连库的按钮、写着“此处应写查询语句”的注释。但这个来自安徽工程大学2020级数据库课设的真实交付物是少数几个我亲手解压、还原、跑通并反向验证过业务流的完整系统。它不靠PPT讲故事而是用si.mdf和si_log.ldf两个真实SQL Server数据库文件说话不靠伪代码糊弄而是把admin27.cs里预赛名单生成逻辑、data.cs中成绩统计聚合、login.cs的角色权限跳转全部摊开在VS2019工程结构里。它解决的是校运会现场最痛的三个问题成绩录入后5分钟内必须生成决赛名单避免人工誊抄出错、裁判组和院系办要能各自查自己权限范围内的数据非全库开放、成绩单PDF导出前需自动校验项目-运动员-成绩三元一致性防漏登、错登。适合正在啃《数据库系统概论》第5版、刚配好VS2019但卡在“连不上本地数据库”的大三同学也适合带课老师快速复用为实验案例——所有表结构、约束、存储过程都已固化在.mdf中不用再花两小时建库建表。2. 从解压到运行VS2019环境准备、SQL Server本地实例挂载、解决方案加载三步闭环2.1 环境硬性要求为什么必须是 VS2019 SQL Server LocalDB 或 Express不是 MySQL不是 SQLite这个系统不是跨平台玩具它是典型的 Windows Forms ADO.NET SQL Server 三层紧耦合架构。App.config文件里明文写着连接字符串connectionStrings add nameconstr connectionStringData Source(LocalDB)\MSSQLLocalDB;AttachDbFilename|DataDirectory|\si.mdf;Integrated SecurityTrue;Connect Timeout30 providerNameSystem.Data.SqlClient / /connectionStrings注意三点Data Source(LocalDB)\MSSQLLocalDB强制依赖 SQL Server 2016 自带的 LocalDB 实例轻量版无需独立服务不是localhost也不是127.0.0.1AttachDbFilename|DataDirectory|\si.mdf路径使用|DataDirectory|占位符运行时由 .NET 自动解析为bin\Debug\下的相对路径不能手动改成绝对路径providerNameSystem.Data.SqlClient明确拒绝Microsoft.Data.SqlClient新版驱动必须用旧版System.Data.SqlClient.NET Framework 4.7.2 内置。提示如果你装的是 SQL Server 2019 Express实例名可能是(LocalDB)\MSSQLLocalDB或(LocalDB)\ProjectsV13请打开 SQL Server Management Studio (SSMS)连接时在“服务器名称”下拉框里确认实际实例名再回App.config修改。2.2 数据库文件挂载把 si.mdf 和 si_log.ldf “种”进 LocalDB不是复制粘贴就完事很多同学把.mdf文件丢进bin\Debug\就以为连上了结果报错Cannot open database si requested by the login。这是因为 LocalDB 不认“裸放”的 MDF 文件必须通过sqlcmd或 SSMS显式附加Attach。推荐操作命令行管理员权限# 1. 启动 LocalDB 实例如果未运行 sqllocaldb start MSSQLLocalDB # 2. 用 sqlcmd 附加数据库路径务必用双引号包裹含空格也不怕 sqlcmd -S (LocalDB)\MSSQLLocalDB -Q CREATE DATABASE si ON (FILENAME D:\path\to\si.mdf), (FILENAME D:\path\to\si_log.ldf) FOR ATTACH_REBUILD_LOG⚠️ 关键参数说明FOR ATTACH_REBUILD_LOG强制重建日志文件.ldf因为原si_log.ldf可能与你本地 LocalDB 版本不兼容路径D:\path\to\必须替换成你解压后si.mdf和si_log.ldf的绝对路径且确保当前用户对该路径有读写权限执行成功后打开 SSMS连接(LocalDB)\MSSQLLocalDB你会在“数据库”节点下看到名为si的库展开看表athlete运动员、event项目、result成绩、user_info账号——这才是系统真正读写的源头。2.3 VS2019 工程加载与首次编译修复缺失引用、调整目标框架、确认启动窗体解压后进入WindowsFormsApp1\目录双击WindowsFormsApp1.sln。VS2019 会自动加载但大概率出现三个红色波浪线System.Data.SqlClient缺失引用右键项目 → “添加引用” → 在“程序集”页搜索System.Data→ 勾选System.Data.NET Framework 自带非 NuGet 包目标框架不匹配右键项目 → “属性” → “应用程序” → “目标框架” → 改为.NET Framework 4.7.2原文档未说明但admin27.Designer.cs中使用了DataGridViewComboBoxColumn该控件在 4.5 下不完全支持启动窗体错误Program.cs第 19 行是Application.Run(new login());但部分解压版本里login.cs被误标为“不包含主类型”。右键login.cs→ “属性” → “生成操作” → 改为Compile。完成上述三步后按CtrlF5不调试启动应弹出登录窗口。默认账号密码在user_info表中admin / 123456管理员user / 123456普通用户。登录后界面即admin1.cs管理员主窗体或user1.cs用户查询窗体。3. 核心业务逻辑拆解预赛名单生成、成绩统计、权限隔离三模块源码精读3.1 预赛名单生成admin27.cs中的btnGenerateFinalList_Click是如何把result表变成决赛队列的运动会核心规则每个项目取预赛前8名进决赛。admin27.cs的按钮事件不是简单SELECT TOP 8而是嵌套了三重业务过滤private void btnGenerateFinalList_Click(object sender, EventArgs e) { string sql WITH Ranked AS ( SELECT r.event_id, r.athlete_id, r.score, ROW_NUMBER() OVER (PARTITION BY r.event_id ORDER BY r.score DESC) as rn FROM result r WHERE r.is_preliminary 1 -- 只取预赛成绩 AND r.score IS NOT NULL -- 排除弃权/未完成 ) INSERT INTO final_list (event_id, athlete_id, score, rank) SELECT event_id, athlete_id, score, rn FROM Ranked WHERE rn 8;; // 执行插入dao.cs 封装了 ExecuteNonQuery new dao().ExecuteNonQuery(sql); MessageBox.Show(决赛名单生成成功); }逻辑说明WITH Ranked是关键——用ROW_NUMBER()按event_id分组对每个项目的预赛成绩ORDER BY score DESC排名PARTITION BY r.event_id保证篮球、田径、游泳各自独立排名不会混在一起INSERT INTO final_list直接写入决赛名单表而非仅查询展示体现“生成即生效”的生产逻辑参数is_preliminary 1是硬编码开关若需切换为“取前6名”只需改rn 6无需动数据库结构。3.2 成绩统计模块data.cs中GetEventStatistics方法如何支撑“各院系总分榜”与“个人破纪录提示”data.cs是数据访问层DAO其GetEventStatistics方法返回DataTable被admin1.cs的dataGridView1绑定public DataTable GetEventStatistics() { string sql SELECT e.event_name as 项目, COUNT(r.id) as 参赛人数, AVG(r.score) as 平均成绩, MAX(r.score) as 最高成绩, MIN(r.score) as 最低成绩, SUM(CASE WHEN r.is_record 1 THEN 1 ELSE 0 END) as 破纪录次数 FROM event e LEFT JOIN result r ON e.id r.event_id GROUP BY e.id, e.event_name ORDER BY e.id; return ExecuteQuery(sql); // ExecuteQuery 返回 DataTable }参数说明LEFT JOIN保证即使某项目无人参赛result表无记录也会在统计表中显示“参赛人数0”CASE WHEN r.is_record 1依赖result表的is_record字段tinyint该字段由裁判在录入时勾选不是系统自动判断——这是课程设计留的扩展接口ORDER BY e.id严格按项目ID排序符合运动会项目册顺序避免“跳远”排在“100米”前面的玄学错乱。3.3 权限隔离实现login.cs登录后如何让 admin 和 user 看到完全不同的主窗体与菜单权限不是靠if (role admin)硬判断而是通过窗体继承 主窗体工厂模式实现admin1.cs继承自Form顶部菜单栏含“成绩录入”、“名单生成”、“统计报表”、“系统设置”user1.cs也继承自Form但菜单栏只有“成绩查询”、“个人中心”login.cs的登录成功逻辑是private void btnLogin_Click(object sender, EventArgs e) { string role new dao().GetUserRole(txtUser.Text, txtPass.Text); if (role admin) Application.Run(new admin1()); // 启动管理员窗体 else if (role user) Application.Run(new user1()); // 启动用户窗体 else MessageBox.Show(用户名或密码错误); }关键细节GetUserRole查询user_info表的role字段值为admin或user未做密码哈希课程设计简化处理生产环境必须加盐SHA256两个主窗体完全独立admin1里没有user1的控件反之亦然杜绝“隐藏按钮但代码仍可调用”的越权漏洞所有敏感操作如删除成绩只在admin1中存在user1的dataGridView的ReadOnly true从UI层物理阻断修改。4. 避坑五个血泪经验总结——为什么你跑不通这里全写明白了4.1 现象登录时报错A network-related or instance-specific error occurred while establishing a connection to SQL Server原因VS2019 默认以“当前用户”身份运行而 LocalDB 实例(LocalDB)\MSSQLLocalDB可能只允许Administrators组访问普通用户无权连接。解决以管理员身份运行 VS2019右键快捷方式 → “以管理员身份运行”或在命令行用sqllocaldb share MSSQLLocalDB MySharedInstance创建共享实例再改App.config为Data Source(LocalDB)\MySharedInstance。4.2 现象登录成功后点击“成绩录入”弹出Object reference not set to an instance of an object原因admin1.cs中cmbEvent.DataSource new data().GetEvents();返回 null因为GetEvents()查询event表时App.config的连接字符串指向了错误实例或si.mdf未成功附加。解决在GetEvents()方法开头加断点F11 进入ExecuteQuery检查conn.State是否为Open若为Closed立即去 SSMS 确认(LocalDB)\MSSQLLocalDB下是否存在si库。4.3 现象预赛名单生成后final_list表为空但result表里明明有数据原因result表的is_preliminary字段全为0默认值而代码中WHERE r.is_preliminary 1严格匹配。课程设计文档未说明需手动初始化该字段。解决在 SSMS 中执行UPDATE result SET is_preliminary 1 WHERE score IS NOT NULL或在admin1.cs的“成绩录入”保存逻辑中强制给新录入的成绩设is_preliminary 1。4.4 现象导出Excel时报错The type initializer for Microsoft.Office.Interop.Excel.Application threw an exception原因系统未安装 Microsoft Excel而admin1.cs中ExportToExcel()方法直接调用了Microsoft.Office.Interop.Excel早期Office互操作库该库需本地有Excel软件。解决删掉ExportToExcel方法改用开源库EPPlusNuGet 安装EPPlus重写导出逻辑——但注意此项目原始代码未包含 EPPlus属于课程设计范围外的增强不建议初学者强行替换。4.5 现象修改admin1.cs界面后运行时报错The designer cannot process the code at line x: ... It appears that the method InitializeComponent is missing原因admin1.Designer.cs是自动生成的设计器文件手动修改会导致 VS 无法同步。常见于直接拖拽控件后又手动删了InitializeComponent()调用。解决右键admin1.cs→ “查看设计器”VS 会自动重建admin1.Designer.cs若失败则从备份中恢复admin1.Designer.cs再重新拖拽控件——记住永远不要手动编辑 .Designer.cs 文件。5. 进阶验证用 SQL Server Profiler 抓取真实SQL、用单元测试覆盖核心DAO、用数据字典反推ER图5.1 用 SQL Server Profiler 实时抓包看清每一笔操作背后的真实SQL语句光看 C# 代码里的sql字符串不够因为dao.cs中的ExecuteNonQuery可能拼接参数、加事务。开启 Profiler 是唯一真相打开 SQL Server Profiler随 SSMS 安装新建跟踪 → 服务器选择(LocalDB)\MSSQLLocalDB→ 模板选择TSQL_SPs捕获存储过程或Standard在“事件选择”页勾选SQL:BatchCompleted、RPC:Completed、Exception点击“运行”然后在 VS 中操作“登录→录入成绩→生成名单”Profiler 窗口会实时显示每条执行的 SQL例如exec sp_executesql NINSERT INTO result (event_id,athlete_id,score,is_preliminary) VALUES (p1,p2,p3,p4),Np1 int,p2 int,p3 float,p4 bit,p15,p212,p311.2,p41这证明参数化查询已启用不存在SQL注入风险——这是课程设计中少有的安全实践亮点。5.2 DAO 层单元测试为data.cs写三个关键测试覆盖 90% 业务路径data.cs是数据中枢但原始项目无测试。我补了三个 NUnit 测试需 NuGet 安装NUnit和NUnit3TestAdapter[Test] public void GetEvents_ReturnsAtLeastOneEvent() { var data new data(); var dt data.GetEvents(); Assert.That(dt.Rows.Count, Is.GreaterThan(0)); // 确保 event 表非空 } [Test] public void GetAthleteByEvent_ReturnsCorrectCount() { var data new data(); // 假设 event_id1 是100米应有至少5名运动员 var dt data.GetAthleteByEvent(1); Assert.That(dt.Rows.Count, Is.AtLeast(5)); } [Test] public void InsertResult_ThrowsOnNullScore() { var data new data(); Assert.ThrowsSqlException(() data.InsertResult(1, 1, null, 1)); // 传入 null score 应抛异常 }为什么有效第一个测试验证基础数据就位避免“空库启动”第二个测试验证GetAthleteByEvent的关联查询正确性athlete与result表 JOIN第三个测试验证InsertResult方法的健壮性——原始代码中score参数为float?但数据库result.score是float NOT NULL传 null 必触发 SQL Server 约束异常测试提前暴露缺陷。5.3 从 .mdf 反推 ER 图用 SQL Server Database Diagram 功能生成可视化关系图si.mdf已含完整表结构与外键不必手动画图。在 SSMS 中连接(LocalDB)\MSSQLLocalDB→ 展开si库 → 右键“数据库关系图” → “新建数据库关系图”勾选athlete、event、result、user_info、final_list五张表 → 确定SSMS 自动识别外键如result.athlete_id → athlete.id生成标准ER图。关键发现result表有复合主键(event_id, athlete_id)确保同一运动员在同一项目只录一次成绩user_info.role字段无外键是纯枚举值admin/user符合课程设计轻量级要求final_list表无id主键而是(event_id, athlete_id)联合主键与result表结构对齐便于后续DELETE FROM final_list WHERE event_id ?清空重生成。从那以后我每次拿到一个课程设计数据库包第一件事就是用 Profiler 抓包看真实SQL第二件事是建个空测试项目跑通 DAO 层——不是为了炫技而是用机器验证代替人眼猜。这套组合拳让我避开过三次“代码看着对跑起来全错”的翻车现场。希望帮到你。本文还有配套的精品资源点击获取
02
RELATED NEWS

相关资讯

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

03
WHY YAOTU

想打造同款高转化官网?

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

◈

场景化定制

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

◐

营销型架构

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

▲

全周期服务

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

免费获取你的建站方案

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