
简介这是一套基于 ASP.NET Core MVC 与 SQL Server 构建的商城系统源码面向具备一定 C# 与 Web 开发基础、希望学习完整电商项目架构的开发者与在校学生。项目采用经典 MVC 分层模式覆盖首页展示、商品列表与详情、购物车、下单页面、订单管理及用户登录等核心业务链路适合作为课程设计、毕业设计或二次开发的参考模板。压缩包共 413 个文件约 31.31MB包含 35 个 cs 源码文件、17 个 cshtml 视图、24 个 css 与 18 个 js 前端资源以及 56 个 dll 依赖库和 52 张 jpg、40 张 png 等商品图片素材另附 mdf 与 ldf 数据库文件可直接还原 SQL Server 2012 数据环境。目前已有 1075 人学习下载。通过阅读源码可掌握控制器与视图的协作方式、购物车与订单状态流转逻辑、数据库表结构设计及前后端资源组织思路便于快速理解 ASP.NET Core MVC 商城项目的整体实现。1. 从一份能跑通的 ASP.NET Core MVC 商城源码说起如果你手头正躺着一份 ASP.NET Core MVC SQL Server 的商城系统源码却卡在“数据库连不上、迁移跑不起来、后台进不去”这三道坎上那这篇笔记就是写给你的。这份资源是一套完整的 B2C 商城实现技术栈锁定在 ASP.NET Core MVC 分层架构 Entity Framework Core SQL Server覆盖商品管理、购物车、订单流转、用户认证这几条主链路。它不是那种只贴几个 Controller 的演示片段而是带完整数据模型、迁移脚本和后台管理入口的可运行工程。适合两类人一是想拿它当课程设计或毕设底座的在校生二是想快速摸清 .NET 商城项目分层套路的初中级开发者。下面我按“先跑起来、再改得动、最后避坑”的顺序拆一遍参数和命令都给到能直接抄的程度。2. 环境搭建与数据库落地从 SQL Server 安装到首个迁移2.1 选 SQL Server 哪个版本别在这步翻车商城系统对数据库的要求其实不高核心就是事务支持和基本的全文检索能力。但版本选错后面连迁移都跑不动。我一般推荐 SQL Server 2019 Developer 或 2022 Developer这两个版本功能完整、授权免费本地开发足够。Express 版也能用但单库 10GB 上限和内存限制在导入大批量商品数据时会难受。安装时有个高频坑身份验证模式一定要选“混合模式”并设好 sa 密码很多人默认选了 Windows 身份验证结果连接字符串里写 sa 账号直接登录失败报的就是“已成功与服务器建立连接但是在登录前发生错误”这类提示。安装完成后用 SSMS 连上去先手动建一个空库命名比如MallDb排序规则保持默认的Chinese_PRC_CI_AS避免中文商品名出现乱码。连接字符串的写法直接决定 EF Core 能不能连上。常见做法是放在appsettings.json的ConnectionStrings节点下{ ConnectionStrings: { DefaultConnection: Serverlocalhost;DatabaseMallDb;User Idsa;PasswordYourStrongPassw0rd;TrustServerCertificateTrue;MultipleActiveResultSetstrue } }这里几个参数值得说清楚。TrustServerCertificateTrue是绕开本地自签证书校验不加的话 .NET 6 默认加密连接会直接抛证书信任异常。MultipleActiveResultSetstrue允许同一连接上并行执行多个命令商城系统里订单查询经常嵌套子查询不开这个容易遇到“已有打开的与此命令相关联的 DataReader”报错。密码别用纯数字或简单词SQL Server 默认开了密码策略太弱的密码在创建登录名时就会被拒。2.2 用 EF Core 迁移把表结构一次性建起来源码里通常已经带好了DbContext和实体类你要做的是生成迁移并更新数据库。先确认项目里装了Microsoft.EntityFrameworkCore.SqlServer和Microsoft.EntityFrameworkCore.Tools这两个包版本要和目标框架匹配。然后在包管理器控制台或终端里执行# 添加初始迁移-o 指定迁移文件输出目录 dotnet ef migrations add InitialCreate -o Data/Migrations # 把迁移应用到数据库真正建表 dotnet ef database updatemigrations add只是根据实体类生成 C# 迁移文件不会碰数据库database update才会把变更同步过去。如果执行 update 时报“无法连接到服务器”先回去检查连接字符串里的 Server 名本地默认实例写localhost或(local)命名实例要写成localhost\实例名。迁移成功后用 SSMS 刷新MallDb应该能看到Products、Orders、OrderItems、AspNetUsers这一系列表。如果表是空的但没报错多半是迁移文件没生成全检查实体类有没有漏掉DbSet声明。2.3 种子数据与后台账号初始化商城系统跑起来第一件事是得有后台管理员账号否则登录页都进不去。源码里一般会有一个DbInitializer或SeedData类在Program.cs启动时调用。典型写法是这样// Program.cs 中创建作用域后调用种子方法 using (var scope app.Services.CreateScope()) { var services scope.ServiceProvider; var context services.GetRequiredServiceApplicationDbContext(); var userManager services.GetRequiredServiceUserManagerIdentityUser(); await DbInitializer.SeedAsync(context, userManager); }SeedAsync里通常做两件事插入几个分类和商品样本数据再创建一个管理员角色和账号。注意种子方法要用await同步等待别写成 fire-and-forget否则应用启动完成时数据还没写完你打开页面看到的是空列表。管理员默认密码一般在DbInitializer里硬编码第一次登录后记得改掉。如果登录时提示“Invalid login attempt”先确认AspNetUsers表里确实有那条记录再看EmailConfirmed字段是不是 false——Identity 默认要求邮箱确认种子数据里要手动把它设成 true。3. 分层架构拆解Controller、Service、Repository 各管什么3.1 商城业务的分层边界怎么划ASP.NET Core MVC 本身只给了 Controller 和 View 两层但商城系统业务复杂直接在 Controller 里写数据库操作会迅速失控。这套源码通常采用 Controller → Service → Repository 的三层结构。Controller 只负责接收请求、做模型验证、返回 View 或 JSONService 层承载业务逻辑比如下单时扣库存、算总价、生成订单号Repository 层封装 EF Core 的查询和保存向上暴露接口。这样分的好处是换 ORM 或加缓存时只动 Repository改促销规则时只动 ServiceController 基本不用碰。判断分层是否合理有个简单标准Controller 里不应该出现DbContext类型的字段或_context.SaveChanges()调用。如果你在 Controller 里看到直接操作数据库的代码说明分层没做到位后期加事务或改并发策略会很痛苦。Service 层注入 Repository 接口Repository 注入DbContext依赖方向是单向的注册在Program.cs里用builder.Services.AddScoped逐个绑定。3.2 商品列表与分页查询的实现细节商品列表是商城最高频的页面分页没做好数据一多就卡。常见做法是在 Repository 里返回IQueryable把分页参数传到 Service 再执行。核心代码大概长这样// Service 层分页查询pageIndex 从 1 开始 public async TaskPagedResultProduct GetProductsAsync(int pageIndex, int pageSize, int? categoryId) { var query _productRepo.Query(); // 返回 IQueryableProduct if (categoryId.HasValue) query query.Where(p p.CategoryId categoryId.Value); var total await query.CountAsync(); var items await query .OrderByDescending(p p.CreatedAt) .Skip((pageIndex - 1) * pageSize) .Take(pageSize) .ToListAsync(); return new PagedResultProduct(items, total, pageIndex, pageSize); }Skip和Take必须在OrderBy之后调用SQL Server 对无排序的分页会直接报错。CountAsync单独走一次查询拿总数别用ToListAsync().Count那样会把全表数据拉到内存里。pageSize建议限制上限比如最大 60防止有人传pageSize100000把数据库拖垮。如果商品表数据量到几十万级Skip的偏移量越大越慢这时候要考虑基于游标的分页或者加覆盖索引但课程设计规模的项目用Skip/Take完全够。3.3 购物车与订单的状态流转购物车这块源码一般用 Session 或数据库两种存法。Session 存法简单但用户换设备就丢数据库存法要建CartItems表关联用户 ID 和商品 ID。下单时把购物车条目转成OrderItems同时扣减Products.Stock。这里有个并发问题两个用户同时买最后一件商品库存可能被扣成负数。常见做法是在扣库存的 SQL 上加条件判断// 扣库存时带条件影响行数为 0 说明库存不足 var affected await _context.Database.ExecuteSqlRawAsync( UPDATE Products SET Stock Stock - {0} WHERE Id {1} AND Stock {0}, quantity, productId); if (affected 0) throw new InvalidOperationException(库存不足);用ExecuteSqlRawAsync直接发 SQL 比先查再改更可靠因为WHERE Stock quantity这个条件在数据库层面保证了不会超卖。订单状态用枚举管理常见流转是Pending → Paid → Shipped → Completed取消订单只能在Pending和Paid阶段做发货后不允许取消。状态字段别用字符串存用int映射枚举查询和比较都更快。4. 避坑与排查那些让项目跑不起来的常见问题4.1 迁移报“数据库已存在”或“表已存在”现象是执行dotnet ef database update时提示对象已存在但你又没手动建过表。原因通常是之前跑过一次迁移数据库里已经有__EFMigrationsHistory表记录了历史而当前迁移文件被重新生成过ID 对不上。解决办法是先删掉数据库重建或者手动清空__EFMigrationsHistory表里对应记录。更稳妥的做法是开发阶段直接用dotnet ef database drop删库再 update别在迁移历史混乱的状态下硬跑。4.2 中文商品名在页面上显示成问号现象是数据库里存的中文正常但页面上显示乱码。原因多半是数据库排序规则不是中文或者连接字符串没指定字符集。解决方式是建库时选Chinese_PRC_CI_AS连接字符串里加Character Setutf8对 SQL Server 不适用SQL Server 用的是排序规则控制。另外检查appsettings.json文件本身的编码确保是 UTF-8 无 BOM否则读出来的配置字符串本身就是乱的。4.3 后台登录后立刻跳回登录页现象是输入正确账号密码页面闪一下又回到登录页。原因通常是 Cookie 认证配置里LoginPath和AccessDeniedPath设错或者app.UseAuthentication()和app.UseAuthorization()的调用顺序反了。认证中间件必须在授权之前顺序错了身份信息还没解析就开始鉴权自然判定为未登录。检查Program.cs里这两行的位置UseAuthentication在前UseAuthorization在后中间不要插入其他改变管道顺序的中间件。4.4 订单提交时提示“连接已关闭”现象是下单操作偶尔失败报连接已关闭或超时。原因是 EF Core 的DbContext生命周期注册成了Singleton多个请求共用一个上下文导致连接状态混乱。正确做法是注册为Scoped每个请求一个实例。检查Program.cs里AddDbContext的默认生命周期就是 Scoped如果你手动改过就要改回来。另外长时间运行的批量操作要考虑用IDbContextFactory创建独立上下文避免请求级上下文被拖太久。4.5 静态资源 404 但文件确实存在现象是 CSS、JS 加载不出来浏览器控制台报 404。原因是app.UseStaticFiles()没调用或者wwwroot目录被排除在发布输出之外。ASP.NET Core 默认不会自动启用静态文件服务必须在管道里显式加上。如果发布后 404检查.csproj里有没有把wwwroot标记为Content并设置CopyToOutputDirectory。常见做法是保持默认别手动改这些项。5. 进阶技巧用 Area 拆分后台与前台以及性能验证方法5.1 用 Area 把 Admin 和 Shop 彻底隔开商城系统前台和后台的 Controller 混在一起路由会越来越乱。Area 是 MVC 自带的分区机制把后台所有控制器放到Areas/Admin/Controllers下路由自动变成/Admin/Product/Index这种前缀。配置步骤不复杂在Program.cs的路由映射里加routes.MapAreaRoute或在MapControllerRoute里加area:exists约束然后在控制器上打[Area(Admin)]特性。视图文件放到Areas/Admin/Views下_ViewStart.cshtml指向后台专用布局。这样前后台的路由、布局、权限策略都能独立配置后台加[Authorize(Roles Admin)]不会误伤前台。5.2 验证查询性能用 SQL Server 执行计划找慢查询项目跑起来之后别只看页面能不能打开要确认查询有没有走索引。SSMS 里开“包含实际执行计划”把商品列表页触发的 SQL 抓出来看。重点看两个地方一是有没有Table Scan或Clustered Index Scan出现说明缺索引二是Sort操作开销占比如果排序开销超过 30%考虑在CreatedAt或Price上建非聚集索引。EF Core 生成的 SQL 可以用LogTo(Console.WriteLine)打到控制台配合EnableSensitiveDataLogging看参数值。索引不是越多越好每个索引都会拖慢写入商品表建两三个覆盖常用查询的索引就够了。5.3 一个我每次都会走的检查习惯从那以后我每次拿到一份 .NET 商城源码都强制走一遍这个顺序先看appsettings.json的连接字符串和Program.cs的中间件顺序再跑dotnet ef database update确认迁移能落地然后用种子账号登录后台最后打开商品列表页看分页和排序是否正常。这四步走完项目能不能用基本就有数了。如果卡在某一步按第 4 章的排查条目对号入座大部分问题都能定位到具体配置项。希望帮到你。本文还有配套的精品资源点击获取