ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

C#进销存系统开发:数据模型与库存流水设计

C#进销存系统开发:数据模型与库存流水设计 简介一套基于C#与.NET框架开发的进销存管理系统完整源码主要面向具备C#基础、想系统学习企业级信息系统开发流程的开发者以及需要毕业设计参考的高校学生。系统覆盖采购、销售、库存、财务和报表分析五大核心业务模块从需求分析、数据库设计到界面编码实现构成完整项目实践闭环。压缩包约5.18MB共109个文件包括49个C#源代码文件承载各功能模块核心业务逻辑、17个resx界面资源文件、16个resources资源文件以及8个ico图标与若干exe可执行程序、数据库文件等目录结构完整便于按模块查阅与二次开发。目前已有58人学习浏览。借助该系统读者可以掌握WinForms桌面应用界面的搭建、SQL Server数据表设计与Entity Framework数据访问方式理解采购订单、库存台账、销售结算等典型业务场景的编码实现方法同时参考其中的多线程处理、数据验证与异常处理设计思路为独立开发或扩展企业管理类项目提供一套完整可运行的参考案例。1. 一套C#进销存管理系统先搞清它解决谁的问题刚接触进销存需求时很容易把项目想窄以为就是“商品增删改再加一个库存字段”。但实际在小门店和贸易公司里采购单、销售单、退货、盘点、成本毛利、应收应付全纠缠在一起Excel拉到一万行之后连“上月到底进了多少货”都说不清。这套C#进销存管理系统目标就是把“进、销、存”变成一条有单据、有流水的闭环每一笔入库能找到供应商和采购单每一笔出库能对到客户和销售单期末库存不是靠某个人拍脑袋填而是由流水累计算出来。适合谁给经营SKU在几百到几万的小团队也给要给这类企业做实施交付的软件从业者。想要真正落地先把数据模型搭正这是后面所有页面、报表的地基。2. 技术选型与数据模型先把库存事务的“根”扎稳进销存系统最怕的不是界面丑而是后期“数据对不上”。技术选型决定开发速度数据表设计决定能不能在原有基础上修修补补跑两年。我一般会先定两件事客户端用什么框架库存数量怎么记录。2.1 客户端与数据库选型WinForms 加什么数据库跑起来最快C# 项目在 Windows 环境做内部管理系统WinForms 到现在依然是性价比最高的选择。WPF 在样式绑定和动画上更强但对进销存这类以表格、弹窗、打印为主的业务基本用不上WinForms 的 DataGridView 拖出来就能做列表事件处理直观新手容易上手老手能做封装而且 ClickOnce 部署比配 IIS 简单得多。数据库要看客户规模选我的默认组合是“单机或两三个客户端用 SQLite局域网五人以上用 SQL Server Express”。SQLite 是单文件库把整个库文件复制走就等于备份部署几乎零成本缺点是写并发弱不适合多个客户端同时大量过账。SQL Server Express 免费容量对进销存完全够用事务和并发控制也更成熟。至于 MySQL性能没问题但 Windows 上还要装服务、配字符集对这套项目属于多出来的维护成本不是首选。技术选型时我习惯先问三个问题客户机房有没有专职 IT 人员最多几个人同时录入要不要对接财务软件答案直接决定了用单机库还是服务库。别一上来就做分布式进销存不是电商中台复杂度应该留给业务规则而不是留给基础设施。使用场景数据库我选择的理由单机只有一两个人录单SQLite单文件备份简单部署零成本局域网 5 人以上同时录单SQL Server Express免费版够用事务和锁机制成熟已有 MySQL 运维经验MySQL可用但 Windows 下多一层服务维护2.2 库存模型用流水表兜底别把“当前库存”当成唯一真源进销存的本质是“每一笔数量变化都要有来源、有去向”。如果只在 Product 表里留一个 InStock 字段每次出库减一、入库加一当时很爽但三个月后出了错根本查不出这笔数量是哪个单子改的。因此正确做法是所有数量变化都写成一条流水记录当前库存只是流水汇总的结果。我习惯拆成两张表StockCurrent 存每个商品当前数量作为列表和报表加速用StockFlow 存每一次数量变化明细到单据号、方向、操作员、时间。后端任何功能想改库存都必须同时写这两张表并且放到同一个数据库事务里。StockCurrent 如果被改乱可以按 StockFlow 重新累加恢复它有后悔药可以吃反过来如果只改 StockCurrent 而不记流水这笔账就永远说不清了。进销存的模型还有一个容易被忽略的点单据状态和库存流水要分离。采购单只有“已审核”状态才生成入库流水草稿状态只保存界面上的商品明细不影响库存。这样才支持“先录单、后审核”的真实业务节奏。否则操作员录一半库存已经变了盘点永远对不上。这个设计在后面的代码里会反复出现。2.3 核心建表 SQL 与 C# 实体从零搭一个最小数据层下面是我在类似项目里常用的核心表结构以 SQLite 语法为例SQL Server 只需要把字段类型做小修改。CREATE TABLE Product ( Id INTEGER PRIMARY KEY AUTOINCREMENT, Code TEXT NOT NULL UNIQUE, -- 商品编码业务上唯一 Name TEXT NOT NULL, -- 商品名称 Spec TEXT, -- 规格型号例如“500ml*24” CategoryId INTEGER, -- 分类ID关联分类表 Unit TEXT DEFAULT 件, PurchasePrice DECIMAL(18,2) DEFAULT 0, SalePrice DECIMAL(18,2) DEFAULT 0, IsActive INTEGER DEFAULT 1 -- 1启用 0停用 ); CREATE TABLE StockFlow ( Id INTEGER PRIMARY KEY AUTOINCREMENT, ProductId INTEGER NOT NULL, Direction TEXT NOT NULL, -- IN入库 OUT出库 Quantity DECIMAL(18,2) NOT NULL, RefOrderNo TEXT, -- 来源单据号如CG-20250101-001 OperatorId INTEGER, Remark TEXT, CreatedAt DATETIME DEFAULT (datetime(now,localtime)) ); CREATE TABLE StockCurrent ( ProductId INTEGER PRIMARY KEY, Quantity DECIMAL(18,2) NOT NULL DEFAULT 0, UpdatedAt DATETIME DEFAULT (datetime(now,localtime)) );设计参数说明商品编码 Code 建了唯一约束重复编码直接由数据库拦截代码里再提示友好信息是从源头防止一物多码。StockFlow.Direction 建议用文本 IN/OUT 而不是 0/1因为日后写统计 SQL 时SUM(CASE WHEN DirectionIN THEN Quantity ELSE -Quantity END)读起来几乎不需要注释。StockCurrent 不建自增 Id直接把 ProductId 当主键因为每个商品在当前库存表里只应有一行。C# 实体类可以这样写列名用驼峰命名Dapper 或手工映射都不累public class StockFlow { public long Id { get; set; } public long ProductId { get; set; } public string Direction { get; set; } // IN入库OUT出库 public decimal Quantity { get; set; } public string RefOrderNo { get; set; } public long OperatorId { get; set; } public string Remark { get; set; } public DateTime CreatedAt { get; set; } DateTime.Now; } public class Product { public long Id { get; set; } public string Code { get; set; } public string Name { get; set; } public string Spec { get; set; } public long CategoryId { get; set; } public string Unit { get; set; } public decimal PurchasePrice { get; set; } public decimal SalePrice { get; set; } public bool IsActive { get; set; } true; }为什么数量用 decimal 而不用 double后面避坑章节会专门讲这里先记住一条纪律金额、数量、单价这三个字段从数据库类型到 C# 属性全部锁死为 decimal中间不要出现 double 转换。CategoryId 用 long是为了以后做多级分类时能用递归查询分类树在进销存里几乎一定会出现。3. 从登录到库存流水核心模块的代码实现与参数调整想真正跑起来最关键的是登录验证、资料防重、库存流水三步。界面按钮多不多不重要这三处的逻辑直接决定系统能不能交给客户用。3.1 登录校验与按钮权限哈希、参数化 SQL、角色三件事登录第一坑就是密码明文存放。进销存里操作员能看到成本价、能冲销单据权限一旦失守整个库存数据都面临风险。所以建用户表时就要把口令哈希化。我一般用“用户名加固定盐再算 SHA256”的方式比直接对密码做哈希抗彩虹表强一点在 C# 里实现并不复杂。本文还有配套的精品资源点击获取
返回列表