尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

.NET 3.5 老 HRMS 源码:数据库还原、配置与工资计算全解析

.NET 3.5 老 HRMS 源码:数据库还原、配置与工资计算全解析 简介一份基于.NET 3.5与SQL Server 2005的人力资源管理系统源码包面向.NET初学者或需要搭建人事管理模块的开发者。系统完整实现员工管理、部门管理、假期管理、人事考勤、员工汇总、加班管理和工资管理等核心业务涵盖人员信息录入、部门增删改查、考勤维护、工资核算等流程有助于理解企业级信息系统的模块划分与数据库表结构设计。压缩包共150个文件以56个C#源代码文件、24个resx界面资源文件和24个resources编译资源为主同时包含SQL Server数据库备份与数据文件、解决方案与配置文件基本可还原数据库后直接运行调试。整体压缩包仅6.71MB目录划分直观便于按需查阅源码与数据库脚本项目代码注释清晰业务模块划分明确可在此基础上快速二次开发。目前已有616人学习下载适合作为.NET三层架构、WinForm界面开发及SQL Server 2005数据库操作的实战参考也可作为课程设计与毕业设计的参考模板。1. 2010 年的 .NET 3.5 HRMS 源码凭什么还值得打开一个 zip 包里躺着 WorkerManage.bak、HRM.exe.config 和一堆 *.Designer.cs这套组合保留了 VS2010 SQL Server 2005 .NET 3.5 时代的典型印记。没上前后端分离没引入 ORM考勤、加班、工资全部靠类型化 DataSet 直接映射数据库表。这类看似过时的源码对现在要接手传统 .NET 项目的团队反而有独特价值七张核心业务表的关系、TableAdapter 的增量更新方式、连接字符串与数据库兼容级别怎么配合都能在一个小而完整的系统里一次看清。下面从还原 WorkerManage.bak 开始把部署、配置、薪资计算和升级到新版 SQL Server 的坑逐个过一遍。2. 从 WorkerManage.bak 到 *.Designer.cs先读懂这套 HRM 的骨架2.1 这堆文件到底在说什么解开 zip 后第一眼不是 .sln 直接躺在根目录而是几个 .Designer.cs 和一个 .bak这经常让新手误判为源码不全。HRM.csproj 才是项目文件主体而 WorkerManage.bak 是 SQL Server 2005 的数据库备份里面装着员工、部门、假期、考勤、加班、工资和系统日志的表结构及初始数据。至于 DesignTimeResolveAssemblyReferencesInput.cache、HRM.csproj.GenerateResource.Cache都是编译过程留下的中间产物和运行时无关可以直接忽略。四个 .Designer.cs 文件分别对应不同的业务域。把它们跟数据库表对起来就能快速定位模块边界文件名对应模块涉及的主要表TimeCardDataset.Designer.cs人事考勤TimeCard、WorkScheduleHolidayManageDataSet.Designer.cs假期管理Holiday、LeaveRequestSalaryDataSet.Designer.cs工资管理Salary、PayrollDetailUserManager.Designer.cs用户登录与日志UserInfo、SystemLog以 TimeCardDataset.Designer.cs 为例编译后会生成 TimeCardDataSet 类内部再拆出 TimeCardDataTable 和 TimeCardTableAdapter。页面层拿到的行对象是强类型直接row.UserName取值编译期就能发现字段名拼错写操作则由 TableAdapter.Update 拼接 UPDATE 语句所有列参数都以前缀传入比直接拼 SQL 字符串更安全。2.2 在设计器里重建数据访问层如果拿到的 .Designer.cs 和 .xsd 同时缺失或者你想增加一个查询最规范的做法是在 VS2010 中新建数据集文件命名保持和原工程一致例如 TimeCardDataset.xsd然后从服务器资源管理器把 SQL Server 2005 里的对应表拖到设计面上。拖入一张表后VS 自动生成三段内容DataTable 结构定义、TableAdapter 的 Fill 与 GetData 查询以及 InsertCommand、UpdateCommand、DeleteCommand 三组命令。这个过程中生成的代码大致长这样namespace HRM.DataSet { public partial class TimeCardDataSet : global::System.Data.DataSet { public TimeCardDataTable TimeCard { get; set; } // 不要在这里手动添加业务方法 // 一旦 xsd 设计器保存整个文件会被重新生成覆盖。 } }要修改查询时正确入口是右键 TableAdapter 选择“配置”只改 SELECT 语句让 VS 把对应的 Command 重新生成。手动去编辑 .Designer.cs 里已生成的方法是高风险操作因为只要 .xsd 设计器再被打开并保存一次整个文件都会被重写所有改动手动内容全部丢失。我在接手类似项目时会先用版本管理工具把原始 .Designer.cs 提交一个基线再动 xsd 设计器这样即便生成结果和预期不一致也能 diff 出差异。2.3 .NET 3.5 与 VS2010 的匹配关系工程文件里 TargetFrameworkVersion 一般写 v3.5对应的编译编译器是 VS2010 内置的 C# 4.0语法上还能用 lambda 和 var但像 async/await、string interpolation 这类特性完全用不了。若你本机只装了 VS2017 或 VS2022打开旧项目时会弹出版本升级提示升级完成后要重点检查两个地方一是所有项目是否统一重定向到新框架版本二是 TableAdapter 生成的global::System.Data.DataSet引用是否解析成功。这里有个常见症状双击 .sln 启动后解决方案资源管理器里项目显示为“不可用”且输出窗口提示CS0246: 找不到类型或命名空间名称。这不是源码坏了而是目标框架被改到 4.x 后部分设计器生成的代码引用了旧程序集中的类型。我的习惯是先把所有项目目标框架统一改成 .NET Framework 4.6.2 或 4.8再执行一次“清理解决方案→重新生成”指令绝大多数编译错误会在这一步消失。3. 部署与连接还原 WorkerManage.bak配置 HRM.exe.config3.1 环境准备与数据库兼容级别最省心的方式是把 WorkerManage.bak 还原到 SQL Server 2005 实例里但 2005 早已停止官方支持新装的 Windows 10/11 上想跑通也有不少兼容性阻碍。日常开发时我更建议先装 SQL Server 2008 R2 或 2012这两个版本能直接识别 2005 备份格式还原后按需再迁往新版。关键点在于还原完成后要立刻确认数据库兼容级别因为 SQL Server 2005 默认兼容级别是 90如果实例自动提高了级别类型化 DataSet 生成的查询语义可能发生变化。确认兼容级别的命令如下SELECT compatibility_level FROM sys.databases WHERE name WorkerManage;如果结果是 90说明数据库还以 2005 模式运行如果高于 90表结构不会变但查询优化器行为会变化例如对NVARCHAR的隐式转换处理更为严格可能让原来正常跑的查询突然变慢。后续是否上调兼容级别我建议放到功能回归测试之后再做而不是一上来就调到最新。3.2 先用 sqlcmd 看逻辑文件名再 RESTORE直接还原前先查看备份内包含哪些逻辑文件避免 MOVE 路径写错。打开命令提示符执行sqlcmd -S .\SQLEXPRESS -E -Q RESTORE FILELISTONLY FROM DISKD:\DB\WorkerManage.bak输出中的 LogicalName 列就是数据文件和日志文件的逻辑名。假设结果分别是 WorkerManage_Data 和 WorkerManage_Log接着执行真正的还原sqlcmd -S .\SQLEXPRESS -E -Q RESTORE DATABASE WorkerManage FROM DISKD:\DB\WorkerManage.bak WITH MOVE WorkerManage_Data TO D:\DB\WorkerManage.mdf, MOVE WorkerManage_Log TO D:\DB\WorkerManage_log.ldf, REPLACEWITH MOVE的作用是把备份内部的逻辑文件映射到当前实例的物理路径不加它时如果备份文件是在别的机器上打包的路径不存在就会报错。REPLACE表示允许覆盖同名数据库只在确认旧数据库无价值时使用。还原完成后跑一次完整性检查排除半途中断导致的数据页损坏sqlcmd -S .\SQLEXPRESS -E -Q DBCC CHECKDB(WorkerManage) WITH NO_INFOMSGS如果输出里出现 error 文本说明备份源本身就有问题什么都不输出才是正常状态。这一步能省下后续排查业务数据不对的很多时间。3.3 配置文件里的连接字符串项目里 app.config 用于编译阶段HRM.exe.config 是发布后 bin 目录下实际生效的配置。两者结构一致修改哪边要看你的运行场景。核心连接字符串如下connectionStrings add nameHRM.Properties.Settings.HRMConnectionString connectionStringData Source.\SQLEXPRESS;Initial CatalogWorkerManage;Integrated SecurityTrue providerNameSystem.Data.SqlClient / /connectionStrings参数含义拆开看参数作用典型值Data SourceSQL Server 实例地址.\SQLEXPRESS、localhost、127.0.0.1,1433Initial Catalog数据库名称WorkerManageIntegrated SecurityWindows 身份验证True / FalseUser ID / PasswordSQL 身份验证账号需配合 Integrated SecurityFalseMultipleActiveResultSets是否允许多个结果集True 时对 DataReader 更友好如果你使用 SQL Server 2005 的 sa 账号登录连接字符串要改成Data Source.\SQLEXPRESS;Initial CatalogWorkerManage;User IDsa;Password你的密码;并去掉 Integrated Security 或设为 False。改完配置后如果程序是从 Visual Studio 启动需要重新生成项目让 app.config 复制到输出目录如果直接跑 exe那就改 HRM.exe.config 后重启进程。4. 核心模块实现考勤、员工汇总与工资数据集4.1 利用 TimeCardDataSet 维护考勤记录考勤模块的数据层来自 TimeCardDataset.Designer.cs其中 TableAdapter 负责把考勤表加载到内存业务规则放在页面层或公共类里。一个典型的日报处理流程是用 GetData 取出当天记录逐行判断上下班时间并更新状态最后把整个 DataTable 交还给 TableAdapter.Update。var ta new TimeCardDataSetTableAdapters.TimeCardTableAdapter(); var card ta.GetDataByDate(DateTime.Today); foreach (var row in card) { if (row.CheckIn.HasValue row.CheckIn.Value.Hour 9) { row.Status 迟到; } } ta.Update(card);这段代码里GetDataByDate 是设计器里可选的带参数查询返回的行结构必须与 TimeCardDataTable 严格一致否则赋值时抛强类型转换异常。Update 内部执行逐行 UPDATE 命令默认会携带所有列作为更新条件这意味着如果两个人同时打开同一张考勤表后提交的人会因为另一列值变化而更新失败。这种并发冲突在单机小系统里不常见但一旦部署到多客户端环境就需要在 DataTable 上启用 RowVersion 或在 SQL 侧加上时间戳列来解决。4.2 员工汇总与部门管理员工汇总页面适合用 DataTable 做内存分组因为人数统计的数据量通常很小。常见做法是先把员工表加载到本地再用 Compute 方法做条件计数var empTa new EmployeeDataSetTableAdapters.EmployeeTableAdapter(); DataTable employeeTable empTa.GetData(); var deptView new DataView(employeeTable); DataTable distinctDept deptView.ToTable(true, DeptID); var summary new DataTable(); summary.Columns.Add(DeptName, typeof(string)); summary.Columns.Add(Count, typeof(int)); foreach (DataRow dept in distinctDept.Rows) { int count (int)employeeTable.Compute( COUNT(EmployeeID), $DeptID {dept[DeptID]}); summary.Rows.Add(dept[DeptID], count); }ToTable(true, DeptID) 按部门 ID 去重并生成一个新表但去重依赖该列本身不存在空值和重复逻辑错误。DeptID 要是允许为空这个写法会把所有空值归成一个组。更稳妥的做法是直接按部门表关联用 LEFT JOIN 一次性查出来SELECT d.DeptName, COUNT(e.EmployeeID) FROM Department d LEFT JOIN Employee e ON d.DeptIDe.DeptID GROUP BY d.DeptName。部门管理本身的增删改查逻辑不复杂删除部门前必须检查该部门下是否仍有员工和考勤记录这一步能用 SQL 外键约束兜底但原工程里未必建了外键所以业务层还要再写一次检查否则会留下孤儿数据。4.3 加班与工资的计算顺序工资管理是业务规则最集中的模块从 SalaryDataSet.Designer.cs 能看出工资表至少包含基础工资、加班费、扣款和实发金额字段。计算逻辑的先后顺序会直接影响结果我一般按下面的流程处理取当月考勤记录统计迟到、早退、缺勤天数。取加班记录按加班小时数和时薪倍数算出加班费。从员工表取基础工资减去缺勤扣款加上岗位补贴。计算实发金额写回工资表。decimal baseSalary employeeRow.BaseSalary; decimal overtimePay (decimal)(overtimeHours * 1.5 * payPerHour); decimal absences lateTimes * 20m earlyLeaveTimes * 20m; decimal finalSalary baseSalary overtimePay - absences;这里的加班倍数 1.5 和每次迟到扣款 20 都是写死在代码里的没有进配置表或参数表是这套源码里最需要重构的地方。如果你准备把它当二次开发底座第一件事就是把这类常量抽到系统参数表否则业务过来改一次扣款规则你就得翻一遍所有计算页面。另一个隐蔽问题是工资计算往往跨月若考勤表没有独立的年月份字段而是依赖记录创建时间月底切换时就会漏算当天 23 点之后的加班记录。建议在所有相关表的查询条件里强制带上WorkDate StartDate AND WorkDate EndDate用半开区间而不是直接比较月份字符串能少踩很多时区边界和时间格式的坑。5. 老项目的两个真实坑.NET Framework 3.5 和 SQL Server 2005 备份迁移5.1 “已安装更高版本”背后的 .NET Framework 3.5 问题在现代 Windows 上运行这套系统最常见的报错是启动瞬间弹出“.NET Framework 初始化错误”或事件查看器里记录 0xc0000135。原因是 .NET Framework 3.5 不随系统默认启用程序用到 3.5 特有的 WCF 和部分数据组件时会直接失败。去“启用或关闭 Windows 功能”勾选“.NET Framework 3.5包括 .NET 2.0 和 3.0”即可恢复这一步需要联网。如果在 HRM.exe.config 里看到 supportedRuntime 只写了 v4.0 或干脆没有建议补齐startup supportedRuntime versionv2.0.50727/ supportedRuntime versionv4.0 sku.NETFramework,Versionv4.8/ /startup把程序重定向到 4.x 后类型化数据集生成代码多数不需要改动。真正容易出问题的是连接字符串解析规则的变化.NET 3.5 时代允许连接字符串里出现未转义的特殊字符4.x 则会直接拒绝解析。密码里带;或者时需要按 4.x 的规则写成键值对并转义否则程序报“格式不正确的连接字符串”。5.2 把 2005 备份迁到现代 SQL Server别一步跨太远SQL Server 2016 及以后版本对过低版本备份的恢复策略非常严格直接从 2005 跳到 2019 而失败的情况并不少见。更稳妥的路径是链式升级先在 SQL Server 2008 R2 或 2012 上还原 WorkerManage.bak确认表和数据完整后再次备份然后把新备份恢复到目标实例。恢复完成先执行完整性检查和兼容级别调整ALTER DATABASE WorkerManage SET SINGLE_USER WITH ROLLBACK IMMEDIATE; ALTER DATABASE WorkerManage SET COMPATIBILITY_LEVEL 100; ALTER DATABASE WorkerManage SET MULTI_USER;把兼容级别设成 100即 SQL Server 2008能让老查询优化器行为尽量保持原样。若你的新实例是最新的 SQL Server 2022兼容级别 100 不在官方支持列表里系统会自动映射到最低支持级别并提示此时建议把目标实例先定位成 2016 或 2019 再走迁移路径。迁移完成后认真核对工资计算中涉及的日期函数2005 的GETDATE()和 2019 的SYSDATETIME()在精度上不同原来存进datetime列的数据不受影响但新写入的数据可能带小数秒老代码若用字符串拼接比较日期就会漏掉部分记录。本文还有配套的精品资源点击获取
返回列表