ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

C#+SQL Server外卖系统课设:数据库设计到三种角色全流程解析

C#+SQL Server外卖系统课设:数据库设计到三种角色全流程解析 简介这份餐饮外卖销售系统数据库设计压缩包基于C#与SQL Server 2019开发覆盖商家、客户、骑手三类角色界面及注册登录模块面向高校数据库课程设计参考适合需要完成同类业务系统设计的中高级学生。压缩包共46个文件整体仅886KB其中13个C#源文件对应各业务窗体与逻辑5组resx/resources界面资源文件用于控件样式另有配置文件、图片素材、可执行程序等解决方案与项目文件齐全目录结构清晰可使用Visual Studio直接打开运行。目前已有1592人学习下载被广泛用于数据库课程设计参考。资源采用扁平化商业级界面设计代码注释详细包含顾客注册、商家登录、商家管理等完整流程清晰体现多角色权限设计与数据库交互思路从界面布局到业务编码均具有较高参考价值是兼顾美观度与可读性的数据库课设高分示例。1. 这就是数据库课设该有的样子从登录到三种角色一套代码全打通做过数据库课设的人都知道最折磨人的不是建几张表、写几条 SQL而是把表里的数据真正用起来登录怎么校验、商家怎么上架商品、骑手怎么接单、订单状态怎么流转。这个资源正好卡在这个痛点上它是一套基于 C# 和 SQL Server 2019 的外卖销售系统包含商家、客户、骑手三种用户界面和独立的注册界面界面走扁平化设计视觉完成度接近商业软件。文件包里是完整的 Visual Studio 解决方案配置好数据库环境后可以直接打开运行。适合正在做数据库课设的高校学生也适合想参考 C# WinForms 连接 SQL Server 这套链路怎么落地的开发者。下面我按自己拆项目的习惯从数据库设计、环境配置、代码逻辑到踩坑记录一层层给你拆开讲。2. 外卖业务的数据模型三张主表怎么设计才不打架2.1 从界面反推表结构客户、商家、骑手是三条独立业务线这个项目里有三个注册入口客户注册、商家注册登录界面则是三者共用。这种设计在数据模型上的第一反应就是——三种用户不能塞进同一张表。很多课设喜欢搞一张“用户表”加一个“角色字段”省事但后续写业务逻辑的时候会非常痛苦客户的收货地址、商家的店铺名、骑手的接单范围这些字段塞在一起表会越来越臃肿查询效率也差。我拆完这个项目后推荐的数据模型是三张主表分立的方案表名核心字段职责边界客户表客户ID、登录名、密码、手机号、收货地址只存客户身份与收货信息商家表商家ID、登录名、密码、店铺名称、营业状态只存商家身份与店铺信息骑手表骑手ID、登录名、密码、手机号、接单状态只存骑手身份与配送信息三张表各自独立登录时按入口分别查不同的表。这种设计的最大好处是权限边界清晰商家界面只能操作商品和订单客户界面只能下单和评价骑手界面只能接单和更新配送状态不会出现“一个用户表里角色字段写错导致权限串了”的尴尬。2.2 订单表与状态流转外卖系统里最考验设计的关联表外卖系统的核心业务是订单而订单表恰恰是课设里最容易设计翻车的地方。很多同学把订单设计成一张“大而全”的表把客户名、商家名、骑手名、商品名全都冗余进去看起来查询方便实际上数据一致性极差。这个项目走的是标准的三范式思路订单表只存外键关联查询时再 JOIN 取名字。常见的核心表设计是这样的表名关键字段说明订单表订单ID、客户ID、商家ID、骑手ID、订单状态、下单时间外键关联三张用户表订单明细表明细ID、订单ID、商品ID、商品数量、单价拆分多商品订单商品表商品ID、商家ID、商品名称、价格、库存归属商家配送表配送ID、订单ID、骑手ID、配送状态、送达时间与骑手强关联订单状态建议用 int 存储而不是中文0 表示已提交、1 表示商家已接单、2 表示骑手配送中、3 表示已完成、4 表示已取消。用数字存储的好处是状态流转的代码判断写起来干净也不会因为中文字符集问题在查询时出幺蛾子。2.3 建库的常见做法脚本化建库比手工点界面靠谱拿到这个资源后你第一件事不是急着打开 Visual Studio而是先把数据库建出来。常见做法是打开 SQL Server Management StudioSSMS新建一个数据库外卖销售系统然后按上面的表结构逐一建表。但我更推荐把建库脚本存成 .sql 文件这样做的好处是答辩时老师问“你的数据库怎么设计的”你直接展示脚本比在 SSMS 里现场点鼠标建表有说服力得多。建表脚本的核心结构大致是这样CREATE TABLE 客户表 ( 客户ID INT IDENTITY(1,1) PRIMARY KEY, 登录名 NVARCHAR(50) UNIQUE NOT NULL, 密码 NVARCHAR(100) NOT NULL, 手机号 NVARCHAR(20), 收货地址 NVARCHAR(200) ); CREATE TABLE 商家表 ( 商家ID INT IDENTITY(1,1) PRIMARY KEY, 登录名 NVARCHAR(50) UNIQUE NOT NULL, 密码 NVARCHAR(100) NOT NULL, 店铺名称 NVARCHAR(100) NOT NULL, 营业状态 INT DEFAULT 1 );这段脚本里有几个细节值得注意。IDENTITY(1,1) 让主键自增避免业务代码里手动维护 ID 出现重复登录名加 UNIQUE 约束是防止注册时出现重复账号的数据库层兜底密码字段用 NVARCHAR(100) 而不是 NVARCHAR(20)因为实际项目中一般会存哈希值而不是明文。商家表的营业状态用 INT 默认 11 表示营业中0 表示休息这样商家界面上切换营业状态时代码只需要 UPDATE 这个字段。订单表关联外键时一个常见的坑是删除客户时如果该客户名下已有订单外键约束会直接报错阻止删除。解决方法是设计时就在订单表上设置 ON DELETE NO ACTION或者干脆在业务层规定——有历史订单的用户不允许物理删除只允许逻辑禁用。这个项目里没有复杂的级联删除需求所以外键约束保持默认即可。3. 把项目跑起来的完整路径从 .sln 到数据库连接串3.1 先读懂解决方案结构sln 和 csproj 各管什么事解压资源包后你会看到一个主项目文件夹 Meituan里面有 Meituan.sln 和 Meituan.csproj。约定俗成的分工是.sln 是解决方案文件记录这个项目包含哪些子项目.csproj 是 C# 项目文件记录编译配置、引用、入口程序等信息。双击 .sln 用 Visual Studio 打开所有窗体文件会出现在解决方案资源管理器里。窗体文件的组织方式是Form 名称 Designer.cs resx 三件套。比如 Login 界面就是 Login.cs业务逻辑、Login.Designer.cs界面布局、Login.resx界面资源。这种结构初学者最容易懵以为三个文件是三个界面其实它们是一个窗体的三面Designer.cs 里是控件的属性赋值逻辑resx 里存的是这个窗体用到的图片、图标等资源真正的代码写在 .cs 里。启动项目是 Program.cs这是 WinForms 应用的入口文件。它的核心逻辑只有三件事我拆出来给你看[STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Login()); }这里的 Application.Run(new Login()) 决定了程序启动后第一个弹出的窗口是登录界面。如果你想改成启动后直接进入商家主界面把 new Login() 换成 new Businesses() 就行。但注意这样的改动只适合测试正式流程必须经过登录验证否则任何人都能跳过登录直接进入系统。3.2 App.config 里的连接字符串最容易翻车的地方这个项目连的是 SQL Server 2019连接字符串配置在 App.config 文件里。App.config 是 C# 程序的配置文件编译后会自动复制到输出目录并改名为 Meituan.exe.config程序运行时从这里读取配置。典型的连接字符串长这样?xml version1.0 encodingutf-8 ? configuration startup supportedRuntime versionv4.0 sku.NETFramework,Versionv4.7.2 / /startup connectionStrings add nameMeituanDB connectionStringData Source.;Initial Catalog外卖销售系统;Integrated SecurityTrue / /connectionStrings /configurationData Source.; 里的点号代表本机默认的 SQL Server 实例。但这里有个坑如果你安装 SQL Server 2019 时给实例起了名字比如 SQLEXPRESS 或自定义名称这个点号就连不上。我一般会建议把 Data Source 写成 计算机名\实例名 的格式比如 DESKTOP-ABC123\SQLEXPRESS这样最稳。判断本机实例名的方法是打开 SSMS登录窗口的服务器名称下拉框里显示的就是完整的实例名。Integrated SecurityTrue 表示用 Windows 身份认证登录数据库。如果你的课设要求用 SQL Server 身份认证改成 User IDsa;Password你的密码 即可。用 SQL Server 认证时密码里有特殊字符比如 、#的话需要对字符做转义处理否则连接字符串解析会出错。3.3 打开即运行的前提先建库再连串实际操作时最常遇到的场景是双击 .sln代码编译没问题一运行就报“在建立与服务器的连接时出错”。原因几乎都是数据库没建或者连接字符串不对。正确的启动顺序是先在 SSMS 里把数据库建好确认连接字符串指向的数据库名和实例名正确再按 F5 运行。如果编译时提示缺少引用看看 csproj 里引用的程序集是不是在你的本机环境里缺失。比如有些封装好的第三方库资源包里没有附带就需要你自己通过 NuGet 还原。但从这个项目的文件列表看引用的都是 System、System.Data、System.Drawing 这类 .NET 自带程序集正常情况下不需要额外装包。4. 登录、注册与三种角色界面业务代码的实现与边界4.1 登录校验的推荐写法参数化查询是底线登录逻辑是整个系统最基础也最容易被攻击的环节。这个项目里登录窗体的职责是接收用户名和密码去对应的表里查是否存在匹配的记录。很多课设代码里直接用字符串拼接 SQL比如 str username str这在单机课设里跑着没事但答辩老师只要问一句“SQL 注入怎么防”你就得当场改代码。这个项目的代码注释里标注了详细的参数说明推荐的写法是参数化查询private void btnLogin_Click(object sender, EventArgs e) { string role cmbRole.SelectedItem.ToString(); // 下拉框选择角色 string loginName txtUsername.Text.Trim(); string password txtPassword.Text.Trim(); if (string.IsNullOrEmpty(loginName) || string.IsNullOrEmpty(password)) { MessageBox.Show(用户名和密码不能为空); return; } string tableName role 商家 ? 商家表 : role 客户 ? 客户表 : 骑手表; string sql SELECT COUNT(*) FROM tableName WHERE 登录名loginName AND 密码password; using (SqlConnection conn new SqlConnection(connStr)) { using (SqlCommand cmd new SqlCommand(sql, conn)) { cmd.Parameters.AddWithValue(loginName, loginName); cmd.Parameters.AddWithValue(password, password); conn.Open(); int count (int)cmd.ExecuteScalar(); if (count 0) { MessageBox.Show(登录成功); // 根据角色打开不同的主界面 } else { MessageBox.Show(用户名或密码错误); } } } }这段代码有三个要点。tableName 是根据角色下拉框动态选择的表名对表名的拼接是安全的因为这是代码里写死的条件赋值不是用户输入密码和用户名都用了参数化方式传入 SqlCommand数据库会把参数当字面量处理从机制上杜绝了注入ExecuteScalar 返回的是首行首列的值COUNT() 正好适合这种只需要判断存在与否的场景。注意 SELECT COUNT() 比 SELECT * 更高效因为数据库不需要回表取完整记录只返回计数结果。4.2 客户注册与商家注册差异在必填字段的校验注册界面分成了客户注册和商家注册两个窗体这是合理的设计。客户的注册信息只需要登录名、密码、手机号、收货地址而商家注册还需要店铺名称。字段不同意味着校验规则和插入的 SQL 语句也不同。客户注册的核心逻辑是三步查重复、校验格式、插入数据。private void btnRegister_Click(object sender, EventArgs e) { string loginName txtLoginName.Text.Trim(); string password txtPassword.Text.Trim(); string phone txtPhone.Text.Trim(); string address txtAddress.Text.Trim(); if (!Regex.IsMatch(phone, ^1[3-9]\d{9}$)) { MessageBox.Show(手机号格式不正确); return; } string checkSql SELECT COUNT(*) FROM 客户表 WHERE 登录名loginName; string insertSql INSERT INTO 客户表(登录名,密码,手机号,收货地址) VALUES(loginName,password,phone,address); using (SqlConnection conn new SqlConnection(connStr)) { conn.Open(); using (SqlCommand cmd new SqlCommand(checkSql, conn)) { cmd.Parameters.AddWithValue(loginName, loginName); int count (int)cmd.ExecuteScalar(); if (count 0) { MessageBox.Show(该用户名已被注册); return; } } using (SqlCommand cmd new SqlCommand(insertSql, conn)) { cmd.Parameters.AddWithValue(loginName, loginName); cmd.Parameters.AddWithValue(password, password); cmd.Parameters.AddWithValue(phone, phone); cmd.Parameters.AddWithValue(address, address); cmd.ExecuteNonQuery(); MessageBox.Show(注册成功); } } }这个实现里有两个细节值得关注。先查重复再插入不是原子操作理论上两个客户端同时注册相同用户名时会产生竞态但对课设场景没关系数据库层面的 UNIQUE 约束兜底了正则表达式 ^1[3-9]\d{9}$ 校验的是国内手机号格式如果你要改成其他规则直接替换正则表达式即可。变量名用了驼峰命名法查重用的 cmd 在 ExecuteScalar 之后处于空闲状态直接再赋值新的 SQL 语句也能复用但用 using 包两层更清晰旧连接会及时释放。4.3 三种角色主界面同源数据的不同业务视图商家、客户、骑手三个主界面对应三个窗体Businesses.cs、Customers.cs、以及骑手相关窗体。三个界面操作的是同一套数据库但业务权限各不相同。商家界面主要操作商品表和订单表客户界面主要操作商品表和订单表但视角不同——客户看到的是可下单的商品列表商家看到的是待处理的订单列表骑手看到的则是待接单的配送任务。这种“一个数据库、三种视图”的设计在代码层面通常体现为对 DataGridView 控件绑定不同的数据源。商家界面加载商品列表的典型写法是private void LoadProducts() { string sql SELECT 商品ID, 商品名称, 价格, 库存 FROM 商品表 WHERE 商家ID商家ID; using (SqlConnection conn new SqlConnection(connStr)) { using (SqlDataAdapter da new SqlDataAdapter(sql, conn)) { da.SelectCommand.Parameters.AddWithValue(商家ID, currentUserId); DataTable dt new DataTable(); da.Fill(dt); dgvProducts.DataSource dt; } } }SqlDataAdapter 扮演的是数据搬运工的角色它先执行 SQL 查出结果再把结果填充进内存里的 DataTable最后通过设置 DataSource 属性一次性把整张表显示在 DataGridView 上。注意 DataSource 赋的是 DataTable 而不是 SqlDataReader因为 DataGridView 需要数据源支持随机访问而 DataReader 是只进只读的流式数据两者绑定会直接报错。5. 避坑指南从打开解决方案到跑通全流程五个典型问题5.1 提示“在建立与服务器的连接时出错。与 SQL Server 建立连接时发生了与网络相关或特定实例的错误”现象F5 运行后弹窗报错错误信息里提到“provider: SQL Network Interfaces”。原因基本是 App.config 里的 Data Source 指向的实例名不对或者 SQL Server 服务没启动。最有效的检查方式是打开 SSMS 尝试连接本机数据库如果 SSMS 能连上而程序连不上就是连接字符串的问题如果 SSMS 也连不上先去 Windows 服务管理器里确认 SQL Server 服务是否在运行。解决把 Data Source 换成 SSMS 登录窗口显示的完整服务器名称。5.2 附加数据库时提示“无法为数据库分配新页面因为文件组已满”现象在 SSMS 里附加数据库文件时报错或者运行一段时间后写入数据失败。这个问题的隐蔽之处在于它不一定发生在附加时刻也可能是数据库文件所在的磁盘空间不足。SQL Server 2019 默认的数据库文件 .mdf 容量耗尽且设置为固定容量时就会报这个错。解决右键数据库 → 属性 → 文件 → 将“自动增长”改为“按百分比增长无限制”或者直接清理磁盘空间。课设期间数据量不大出现这个报错大概率是磁盘满了。5.3 打开窗体时提示“找不到资源文件”现象编译通过但运行到某个窗体时抛异常提示找不到 .resx 中引用的资源。常见原因是把项目文件夹移动了位置导致资源文件路径失效。这个项目里登录界面和注册界面都用到了图片资源这些图片在 Resources 文件夹下。建议不要移动资源包的目录结构保持解压后的原始层级。如果已经移动了右键 resx 文件 → 重新加载再检查图片文件是否被误删。5.4 界面中文显示乱码现象窗体上的中文标签或按钮文字显示为菱形问号。原因通常是系统区域设置不是中文Windows 的非 Unicode 程序语言设置不匹配。解决控制面板 → 区域 → 管理 → 更改系统区域设置 → 勾选 Beta 版 UTF-8 或改为中文简体。对于数据库里查出来的中文乱码则要考虑 SQL Server 排序规则SQL Server 2019 默认排序规则 Chinese_PRC_CI_AS 一般不会出问题。5.5 注册后无法登录提示用户名或密码错误现象注册界面提示注册成功但回到登录界面输入同样账号密码却报错。这是最典型的课设翻车点原因有两个一是注册时密码框里多了空格登录时 Trim() 去掉了而注册时没去掉二是注册和登录查询的不是同一张表——注册写入了客户表登录却查了商家表。解决检查注册和登录代码里操作的表名是否一致同时在所有文本框取值的入口统一加 Trim() 去空格处理。6. 把课设从“能跑”变“能答辩”三个值得加的功能点先确认一个残酷事实课设答辩时老师看的不只是界面好不好看更重要的是你的代码有没有“设计感”。这个资源的界面完成度已经很高但如果你想让成绩再上一个档次我建议在现有基础上加三个功能点每个的工作量都在一晚上以内。第一把订单状态的判断逻辑封装成存储过程。现在项目里修改订单状态的代码大概率是直接拼 UPDATE 语句。用存储过程封装的好处是状态流转的逻辑收敛在数据库端C# 代码只负责调用答辩时老师问“订单状态怎么保证不跳变”你直接展示存储过程里的 CASE 判断。CREATE PROCEDURE usp_UpdateOrderStatus OrderID INT, NewStatus INT AS BEGIN UPDATE 订单表 SET 订单状态 NewStatus WHERE 订单ID OrderID ENDC# 端调用时用 SqlCommand 指定 CommandType.StoredProcedure然后 AddWithValue 传参即可。这个小改动会让你的代码明显比同组同学“高级”。第二给 DataGridView 加一个明细展示。现在商品列表加载后双击行大概率没有反应。你可以给 DataGridView 注册 CellDoubleClick 事件弹出一个小窗体展示该商品的销量或者该订单的明细项。这个功能不强但对答辩很有效——它是“主从表联动”的直接演示数据库课设最看重的就是表间关联。第三把密码改成哈希存储。现在注册表里存的还是明文密码虽然课设够用但你可以在注册代码里加一行 SHA256 哈希计算登录时对输入密码做同样处理再比较。改动量极小但老师在答辩时问“安全性怎么考虑”时你至少有话可答而且还能原理解释清楚。说到底数据库课设的核心竞争力不是“我把界面画得多好看”而是“我理解表与表之间的关系并且能在代码里把这种关系正确地表达出来”。从那次以后我每次做类似的 C# SQL Server 课设都会强制自己先画一遍实体关系草图再去写任何代码这个习惯让我的课程设计再没翻过车。希望这份拆解能帮到你。本文还有配套的精品资源点击获取
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表