ARTICLE DETAIL

资讯详情

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

ASP.NET油田计划生产系统毕设实战:C#+SQL Server从建表到统计

ASP.NET油田计划生产系统毕设实战:C#+SQL Server从建表到统计 简介这是一套基于ASP.NET C#与SQL Server开发的油田计划生产管理系统采用B/S模式构建完整源码与数据库齐全。系统包含权限管理、用户管理、矿名管理、产油管理、生产计划管理、公告管理及图表展示等功能模块适合计算机相关专业学生用于毕业设计或课程设计参考。压缩包以rar格式发布大小约2.76MB页面未提供具体文件清单但开发环境为VS2010数据库为SQL Server 2008及以上版本数据库文件名aspnetsyoutian.mdf系统入口为login.aspx管理员账号与密码均为admin。目前已有151人学习下载可作为同类课题的重要参考。除完整前后台代码外还附带数据库文件支持直接导入运行与二次开发。通过生产计划管理、产油数据管理以及图表展示可快速理解油田业务数据的组织方式与B/S架构的实现思路是一份实用性较强的毕业设计参考源码。1. 别急着换题目asp.net油田计划生产系统到底在做什么收到“计算机毕业设计asp.net油田计划生产系统”这个题目很多人的第一反应是“石油行业离我太远”或者觉得 ASP.NET 是老技术怕答辩被问住。我的看法正好反着这是一个业务边界清晰、技术栈完整、演示效果好的 web 结构项目。剥开“油田”外壳核心就是三件事——用 C# 写页面逻辑用 VS 开发和调试用 SQL Server 存计划与产量数据再把月度计划、实际产量、完成率统计串成一个能演示的系统。它对数据库设计、三层结构、列表分页、统计查询的覆盖都很典型适合大多数计算机专业同学。这篇笔记按业务模型、数据库、页面实现、排错和演示验证展开看完能直接照着做。2. 业务模型与选型为什么 Web Forms 是毕业设计的稳妥牌2.1 油田计划生产的业务闭环计划、分解、上报、统计这个系统名字带“油田”但业务逻辑和普通的生产计划管理系统没有本质区别。核心闭环是管理层年初定下产量目标把任务按月分解到各采油单位各油井按天或按旬把实际产量上报系统自动汇总出每个月的完成率。落到实体上常见做法是准备这样一组数据用户区分管理员和上报员、油田区块、油井基础信息、月度生产计划、实际产量记录。角色和权限不用做复杂管理员负责计划编制和数据审核普通用户负责产量录入角色在页面功能上一个多一个少论文里也好画用例图。这个闭环直接对应了系统的页面地图登录页进入首页看板然后是计划管理、产量上报、统计报表三个核心模块。计划管理解决“定多少”产量上报解决“实际多少”统计报表解决“差多少”。三条模块的数据流是一条直线不管做分层架构还是画 ER 图都很好向导师交代。答辩时老师问“系统解决什么问题”你就沿着这个闭环讲一遍逻辑是自洽的。2.2 ASP.NET Web Forms vs MVC开发效率和论文可写性之间的平衡环境选型这一步直接决定后面一个月的开发节奏。先澄清一个容易混淆的点这里说的 VS 是 Visual Studio不是日常拿来装插件的 VS Code。Visual Studio 才是 ASP.NET Web Forms 的完整开发环境VS Code 虽然也能写 C#但建项目、拖控件、调试 IIS 都别扭毕设主战场老老实实用 Visual Studio。框架选型我一般建议选经典 ASP.NET Web Forms 而不是 ASP.NET Core MVC理由很现实对比项Web Forms (.NET Framework 4.x)ASP.NET Core MVC列表页开发GridView 绑定数据源即可出分页表格需要手写控制器、视图、模型绑定事件处理按钮点击事件直观路由、过滤器、中间件概念多毕业设计绘图三层架构图好画请求管线图不好讲部署IIS 发布简单需要配置托管模块或 Kestrel学习成本低看完 GridView 就能上手高光依赖注入就够说半小时Web Forms 像模板排版MVC 像从零调样式。做毕业设计的核心目标是在有限时间里交付一个能跑、能演示、能写进论文的系统Web Forms 把界面交互的活干了省出来的时间可以花在数据库设计和统计逻辑上这两块才是答辩老师真正会追问的地方。如果导师没有硬性要求用 Core就选 Web Forms。2.3 环境版本VS、SQL Server、.NET Framework 怎么凑成一套能跑的组合无论源码是从哪个渠道拿到的先确认三个版本能匹配。常见组合是 Visual Studio 2019/2022 社区版 .NET Framework 4.6.1 或 4.7.2 SQL Server 2016/2017/2019 Express 版。VS 2022 现在仍然支持 .NET Framework 4.x 项目可以放心打开老项目。SQL Server 建议装 Express 版它是免费的虽然有 10GB 库大小限制但毕业设计的数据量撑死几十万行性能完全够。连接字符串写在 Web.config 的 connectionStrings 节点里本地调试时 data source 可以写“(localdb)\MSSQLLocalDB”或者“.”等部署到 IIS 再改成实际的服务器 IP。Visual Studio 自带的 SQL Server Express 实例也可以直接用但要注意它和独立安装的实例可能争抢端口。提示如果 SQL Server 安装阶段反复失败优先检查是不是之前装过但没卸载干净用 SQL Server 安装中心自带的“删除”功能清理残留实例比手动删注册表安全得多。3. 数据库先行SQL Server 计划生产库的表设计与关键约束3.1 六张核心表从用户、油田到月度计划的建表脚本数据库是这套系统的地基很多毕业设计翻车不是写在页面层而是炸在建表和字段设计上。我按常见做法把表拆成六张SysUser 用户表、OilField 油田表、OilWell 油井表、MonthPlan 月度计划表、ProductionRecord 产量记录表、OperationLog 操作日志表。下面是可直接执行的建表脚本-- 用户表管理员与上报员共用 CREATE TABLE SysUser ( UserId INT IDENTITY(1,1) PRIMARY KEY, UserName NVARCHAR(50) NOT NULL UNIQUE, Password NVARCHAR(100) NOT NULL, RealName NVARCHAR(20) NOT NULL, RoleType INT NOT NULL DEFAULT 1 -- 1管理员, 2上报员 ); -- 油田/区块表 CREATE TABLE OilField ( FieldId INT IDENTITY(1,1) PRIMARY KEY, FieldName NVARCHAR(50) NOT NULL, Manager NVARCHAR(20) NULL ); -- 油井基础信息 CREATE TABLE OilWell ( WellId INT IDENTITY(1,1) PRIMARY KEY, WellCode NVARCHAR(20) NOT NULL UNIQUE, WellName NVARCHAR(50) NOT NULL, FieldId INT NOT NULL, WellType NVARCHAR(20) NULL, -- 采油井/注水井 Status BIT NOT NULL DEFAULT 1, -- 1在用, 0停用 FOREIGN KEY (FieldId) REFERENCES OilField(FieldId) ); -- 月度生产计划表 CREATE TABLE MonthPlan ( PlanId INT IDENTITY(1,1) PRIMARY KEY, WellId INT NOT NULL, PlanMonth NVARCHAR(7) NOT NULL, -- 统一 2025-01 格式 PlanOutput DECIMAL(18,2) NOT NULL, CreateTime DATETIME NOT NULL DEFAULT GETDATE(), CONSTRAINT UQ_Plan_WellMonth UNIQUE (WellId, PlanMonth), FOREIGN KEY (WellId) REFERENCES OilWell(WellId) ); -- 实际产量记录表 CREATE TABLE ProductionRecord ( RecordId INT IDENTITY(1,1) PRIMARY KEY, WellId INT NOT NULL, RecordDate DATETIME NOT NULL, ActualOutput DECIMAL(18,2) NOT NULL, ReporterId INT NOT NULL, Remark NVARCHAR(200) NULL, FOREIGN KEY (WellId) REFERENCES OilWell(WellId), FOREIGN KEY (ReporterId) REFERENCES SysUser(UserId) ); -- 操作日志表记录谁在什么时间改了哪口井的计划 CREATE TABLE OperationLog ( LogId INT IDENTITY(1,1) PRIMARY KEY, UserId INT NOT NULL, ActionType NVARCHAR(50) NOT NULL, TargetCode NVARCHAR(50) NULL, LogTime DATETIME NOT NULL DEFAULT GETDATE(), FOREIGN KEY (UserId) REFERENCES SysUser(UserId) );逻辑说明OilWell 的 WellCode 用 NVARCHAR 而不是 INT因为井号通常带前缀和零填充MonthPlan 用 (WellId, PlanMonth) 复合唯一约束从数据库层面杜绝一口井同一个月出现两个计划。OperationLog 表是加分项论文里可以写“审计功能”演示时故意删一条数据再展示日志有记录导师对这类细节印象很深刻。参数说明DECIMAL(18,2) 是产量和计划的统一精度整数位 16 位足够装几十万吨PlanMonth 用 NVARCHAR(7) 而不是 DATE是因为月份天然没有日用字符串反而避免“2025-01-01 00:00:00”这种时间戳干扰。3.2 字段规范数值精度、唯一约束和统计查询的索引字段设计有三个老生常谈但必须检查的点。第一产量和计划全部用 decimal(18,2)不要为了省事用 float。float 是浮点近似单条记录看不出问题一旦做完完成率统计0.10.2 变成 0.30000000000000004 这种事会在答辩演示里被当场看穿。第二唯一约束必须建在数据库层。程序里“先查后插”不是保险用户在页面快速点两下保存按钮两个请求可能同时通过查询然后插出重复数据MonthPlan 的 UQ_Plan_WellMonth 就是干这个的。第三高频查询是“某月全油田的完成率”索引往查询方向建CREATE INDEX IX_Prod_WellDate ON ProductionRecord (WellId, RecordDate); CREATE INDEX IX_Plan_WellMonth ON MonthPlan (WellId, PlanMonth);数据量小时这两个索引可有可无但系统跑一年后 ProductionRecord 会有几万行没索引的 SUM 和 JOIN 会让统计页卡到超时。各表之间的关键字段可以对照下面这张清单检查表主键关联字段统计参与SysUserUserIdReporterId无OilFieldFieldIdOilWell.FieldId按区块筛选OilWellWellIdMonthPlan/ProductionRecord 的 WellIdStatus 过滤在用井MonthPlanPlanIdWellIdPlanOutput 作分母ProductionRecordRecordIdWellId, ReporterIdActualOutput 作分子3.3 初始化数据脚本让毕业演示不靠在界面上手敲数据系统第一次启动界面空荡荡导师连点两下就没了兴趣。初始化脚本至少生成两类数据基础档案油田、油井和近两年的计划。生成基础档案用 INSERT 没问题生成计划用 CROSS JOIN 最省事;WITH Months AS ( SELECT 2024-01 AS M UNION ALL SELECT 2024-02 UNION ALL SELECT 2024-03 -- 按需补全到 2025-12 ) INSERT INTO MonthPlan (WellId, PlanMonth, PlanOutput) SELECT w.WellId, m.M, ROUND(800 RAND(CHECKSUM(NEWID())) * 200, 2) FROM OilWell w CROSS JOIN Months m WHERE w.Status 1;逻辑说明CROSS JOIN 让每口井与每个月组合一次PlanOutput 用 800 到 1000 之间的随机数模拟不同油井的产能差异。RAND(CHECKSUM(NEWID())) 是 SQL Server 里常用的“每次执行都产生不同随机数”的写法如果直接写 RAND()同一批次所有行会拿到同一个随机数计划数值全都一样。产量数据的生成脚本放到第 6 章那里有一段更完整的模拟上报脚本可以一并跑。到这里数据库已经准备好了下一步开始写页面。4. 核心页面实现计划编制、产量上报与完成率统计的 C# 代码4.1 计划编制页面GridView 批量录入与保存页面布局按 web 结构常见做法上面一个 DropDownList 选月份中间一个 GridView 列出该月在用油井最后一列是计划产量输入框底部一个保存按钮。GridView 用模板列写输入框才能让每一行都能编辑。数据源查询要同时查出井号和现有计划值没有计划的井 PlanOutput 返回 NULL绑定时显示为空。asp:GridView IDgvPlan runatserver AutoGenerateColumnsFalse DataKeyNamesWellId,WellCode OnRowDataBoundgvPlan_RowDataBound Columns asp:BoundField DataFieldWellCode HeaderText井号 / asp:BoundField DataFieldWellName HeaderText井名 / asp:TemplateField HeaderText计划产量(吨) ItemTemplate asp:TextBox IDtxtPlan runatserver Width80 Text%# Eval(PlanOutput) % / /ItemTemplate /asp:TemplateField /Columns /asp:GridView保存按钮的 C# 逻辑用事务包一组“存在即更新、不存在即插入”的操作protected void btnSave_Click(object sender, EventArgs e) { string month ddlMonth.SelectedValue; // 形如 2025-01 string connStr ConfigurationManager.ConnectionStrings[DefaultConn].ConnectionString; using (SqlConnection conn new SqlConnection(connStr)) { conn.Open(); SqlTransaction tran conn.BeginTransaction(); try { foreach (GridViewRow row in gvPlan.Rows) { string wellId gvPlan.DataKeys[row.RowIndex][WellId].ToString(); var txtPlan row.FindControl(txtPlan) as TextBox; decimal planValue; if (!decimal.TryParse(txtPlan.Text.Trim(), out planValue)) { throw new FormatException(井号 wellId 的计划产量不是有效数字); } // 合并写目标表存在则更新不存在则插入 string sql IF EXISTS (SELECT 1 FROM MonthPlan WHERE WellIdwellId AND PlanMonthmonth) UPDATE MonthPlan SET PlanOutputplan WHERE WellIdwellId AND PlanMonthmonth ELSE INSERT INTO MonthPlan (WellId, PlanMonth, PlanOutput) VALUES (wellId, month, plan); SqlCommand cmd new SqlCommand(sql, conn, tran); cmd.Parameters.AddWithValue(wellId, wellId); cmd.Parameters.AddWithValue(month, month); cmd.Parameters.AddWithValue(plan, planValue); cmd.ExecuteNonQuery(); } tran.Commit(); BindGrid(month); // 保存后重新绑定回显最新计划值 } catch { tran.Rollback(); throw; } } }参数说明decimal.TryParse 比 Convert.ToDecimal 更有容错性空行或“800.5吨”这种误输入不会让页面直接崩溃SQL 全程用 SqlParameter 参数化不要用 string.Format 拼接那是评审老师最爱挑的注入漏洞。IF EXISTS 合并写配合数据库唯一约束等于双保险用户连续点两次保存也不会报主键冲突。4.2 产量上报页面同一天防重与事务提交产量上报页面面向普通用户。操作流程是进入页面看到当天未上报的油井列表勾选要上报的井、填入实际产量、点提交。防重逻辑放在 SQL 端比 C# 端先查再插可靠protected void btnReport_Click(object sender, EventArgs e) { string connStr ConfigurationManager.ConnectionStrings[DefaultConn].ConnectionString; string today DateTime.Today.ToString(yyyy-MM-dd); using (SqlConnection conn new SqlConnection(connStr)) { conn.Open(); foreach (GridViewRow row in gvWell.Rows) { var cb row.FindControl(chkSelect) as CheckBox; if (cb null || !cb.Checked) continue; string wellId gvWell.DataKeys[row.RowIndex][WellId].ToString(); var txtActual row.FindControl(txtActual) as TextBox; decimal actual; if (!decimal.TryParse(txtActual.Text.Trim(), out actual)) continue; SqlCommand cmd new SqlCommand( IF NOT EXISTS (SELECT 1 FROM ProductionRecord WHERE WellIdwellId AND CONVERT(varchar(10), RecordDate, 120)today) INSERT INTO ProductionRecord (WellId, RecordDate, ActualOutput, ReporterId) VALUES (wellId, today, actual, uid) ELSE UPDATE ProductionRecord SET ActualOutputactual WHERE WellIdwellId AND CONVERT(varchar(10), RecordDate, 120)today, conn); cmd.Parameters.AddWithValue(wellId, wellId); cmd.Parameters.AddWithValue(today, today); cmd.Parameters.AddWithValue(actual, actual); cmd.Parameters.AddWithValue(uid, Session[UserId]); cmd.ExecuteNonQuery(); } } BindToday(); }逻辑说明页面里勾选多行的场景必须在同一个连接对象上逐个执行如果中间某行提交失败可以把循环包进 SqlTransaction 一起回滚。CONVERT(varchar(10), RecordDate, 120) 把 DATETIME 截为“yyyy-MM-dd”样式码 120 是 ISO 8601别写成 101那是美国格式 MM/dd/yyyy这个差异在跨机器部署时会出现日期错乱这种像玄学一样的问题。Session[UserId] 是登录时写入的会话值产量记录带上上报人统计完成率的同时还能查“谁报的”论文里可以写成责任追溯。参数化的四个值分别对应井号、日期、产量和上报人保持顺序一致。4.3 完成率统计一条 SQL 出月度对比数据统计页是答辩的关键。实现方式是把月度计划、实际产量、完成率放在一张表格里按完成率倒序SQL 的连贯写法是SELECT w.WellCode, w.WellName, ISNULL(p.PlanOutput, 0) AS PlanOutput, ISNULL(SUM(r.ActualOutput), 0) AS ActualOutput, CASE WHEN ISNULL(p.PlanOutput, 0) 0 THEN 0 ELSE ROUND(ISNULL(SUM(r.ActualOutput), 0) / p.PlanOutput * 100, 2) END AS Rate FROM OilWell w LEFT JOIN MonthPlan p ON w.WellId p.WellId AND p.PlanMonth month LEFT JOIN ProductionRecord r ON w.WellId r.WellId AND CONVERT(varchar(7), r.RecordDate, 120) month WHERE w.Status 1 GROUP BY w.WellCode, w.WellName, p.PlanOutput ORDER BY Rate DESC;参数说明两边都用 LEFT JOIN目的是把“有计划没产量”和“有产量没计划”的井都保留在结果里。如果误用 INNER JOIN漏数据的井会直接消失统计口径不完整。CONVERT(varchar(7), r.RecordDate, 120) 截出“yyyy-MM”和 MonthPlan.PlanMonth 的字符串格式对齐。如果数据量超过几十万行更好的做法是把 CONVERT 换成范围条件r.RecordDate monthStart AND r.RecordDate DATEADD(month, 1, monthStart)避免在 JOIN 条件里做转换导致索引失效。CASE 里的 ISNULL(p.PlanOutput, 0) 0 判断是防止计划为 0 的井在统计表里出现除零错误。5. 排错与避坑VS 与 SQL Server 组合下的高频翻车现场5.1 安装失败无法找到数据库引擎启动句柄现象SQL Server 2016/2017/2019 安装中途报错“无法找到数据库引擎启动句柄”随后安装程序回滚服务列表里看不到 SQL Server 服务。原因常见两种。一是这台机器装过 SQL Server 但卸载不干净注册表里残留旧实例信息二是安装时勾选了太多功能Reporting Services 或 Analysis Services 被数据库引擎依赖但系统权限不足导致引擎起不来。解决先到“控制面板→程序和功能”卸载所有 SQL Server 相关组件再打开 SQL Server 安装中心用“删除”功能清残留实例。重装时只勾“数据库引擎服务”不勾其他组件。安装完成后如果服务仍然没有启动打开“SQL Server 配置管理器”找到实例名右键“启动”看 Windows 事件日志确认具体失败原因。如果和本机已有实例端口冲突把 TCP/IP 端口改为 1433 并重启服务。5.2 保存崩了字符串转数字的输入清洗现象产量文本框输入“120.5吨”或“1,200”点保存后页面黄页报错 Input string was not in a correct format断点进去发现 Convert.ToDecimal 抛了异常。原因Convert.ToDecimal 只认纯数字字符串带中文单位或千分位逗号的输入会绕过前端验证直达服务端导致转换失败。这是页面最常见的数据脏输入问题。解决外层先做一次清洗再 TryParse。比较稳的写法是string raw txtPlan.Text.Trim().Replace(,, ).Replace(吨, ); decimal val; if (decimal.TryParse(raw, NumberStyles.Number, CultureInfo.InvariantCulture, out val)) { // 保存逻辑 } else { lblMsg.Text rowIndex 号井的产量不是合法数字; }把清洗逻辑统一封装成一个私有方法所有上报页面共用避免每个页面各写一遍。这个问题在答辩代码评估里反而是加分项因为大部分同学会直接栽在这里。5.3 连接不上本地能跑换台电脑就连不上库现象自己机器上 IIS 跑得好好的把项目部署到服务器或者让老师用局域网访问页面报“无法与 10.10.8.149 建立连接”或者 Login timed out。原因Web.config 里的连接字符串写死了“localhost”或“(localdb)”换机器后实例名和 IP 完全对不上。更隐蔽的是 SQL Server 默认没开 TCP/IP 协议即使 IP 写对了1433 端口也没在侦听。解决三层都要改到位。第一层连接字符串 data source 写 SQL Server 所在机器的实际 IP第二层SQL Server 配置管理器里启用“SQL Server 网络配置”的 TCP/IP 协议默认端口填 1433第三层Windows 防火墙入站规则放行 1433 端口。验证顺序是SQL Server 服务正常 → TCP/IP 已启用 → telnet IP 1433 能通 → 网页能登录。注意 sa 账户默认可能被禁用要用 Windows 身份登录进去启用或新建应用账号。5.4 GridView 翻页后数据丢失ViewState 和事件模型现象GridView 开启分页后首页数据正常点第 2 页再点保存FindControl 返回 null或者 GridView 里的 TextBox 内容全部变成空白。原因Web Forms 的 GridView 分页依赖 ViewState 保存整张网格的行状态。如果为了减负把 EnableViewState 设为 False或者数据量过大导致 ViewState 截断翻页后回发就找不到行控件。解决翻页时不要自定义按钮直接用 GridView 自带的分页条OnPageIndexChanging 事件里重新绑定数据源并设置 e.NewPageIndex不要靠 ViewState 恢复行数据。数据量如果超过 1000 行直接用 SQL Server 2012 以后支持的 OFFSET FETCH 做数据库分页只把当前页数据加载到控件问题从根上解决。5.5 外键拦路删不掉有历史记录的油井现象删除一口油井时页面报 The DELETE statement conflicted with the REFERENCE constraint明明井已经停用了为什么还是删不掉。原因OilWell 被 MonthPlan 和 ProductionRecord 外键引用历史计划记录和产量记录还在物理删除自然会被外键拦截。如果把外键改成 ON DELETE CASCADE会把历史数据连带删光统计报表直接失真坚决不能这么干。解决永远不做物理删除。把 Status 置 0 表示停用停用井不参与新计划编制但历史统计仍然保留。删除按钮在前端先检测子表是否有数据有就提示“该油井存在计划或产量记录不能删除”没有再执行 DELETE。这个设计在论文里可以名正言顺地写成一个小节“基于逻辑删除的数据一致性方案”比硬刚外键高级得多。6. 答辩演示的最后一步用 SQL 模拟数据并验证统计口径演示环节最怕两件事数据库空荡荡统计页一片空白或者数据是手工编的“计划100、实际80”这种整数一眼假。用一段 SQL 脚本为每口井生成 12 个月的产量上报记录让产量在合理区间内随机波动完成率出现百分比小数图表有起伏导师就会觉得数据真实可信。DECLARE wellId INT, monthStart DATE, baseOutput DECIMAL(18,2) DECLARE well_cursor CURSOR FOR SELECT WellId FROM OilWell WHERE Status 1 OPEN well_cursor FETCH NEXT FROM well_cursor INTO wellId WHILE FETCH_STATUS 0 BEGIN SET monthStart 2024-01-01 WHILE monthStart 2025-01-01 BEGIN SET baseOutput 20 RAND(CHECKSUM(NEWID())) * 10 INSERT INTO ProductionRecord (WellId, RecordDate, ActualOutput, ReporterId) SELECT wellId, DATEADD(day, n.number, monthStart), ROUND(baseOutput RAND(CHECKSUM(NEWID())) * 3, 2), 1 FROM (SELECT TOP 20 number FROM master..spt_values WHERE typeP AND number BETWEEN 1 AND 28 ORDER BY NEWID()) n SET monthStart DATEADD(month, 1, monthStart) END FETCH NEXT FROM well_cursor INTO wellId END CLOSE well_cursor DEALLOCATE well_cursor脚本用游标遍历在用油井逐月生成 20 天的上报记录。master..spt_values 是系统辅助表typeP 时 number 取值TOP 20 随机取 20 个序号当作“日”限制在 1 到 28 之间不会跨月。产量等于基础值加随机波动完成率不会变成整齐划一的整数。跑完脚本后做两步验证任选一口井一个月把产量记录按天 SUM 和统计页对比一致说明 GROUP BY 口径正确再把某口井某月计划改成 0确认统计页显示完成率为 0 而不是除零报错。这两个验证做完答辩现场老师怎么抽数据都能当场解释。做毕业设计我自己的血泪教训是日期格式第一天就统一用“yyyy-MM-dd”数字解析统一用 TryParseSQL 统一参数化。这三点决定了代码评审是“功能完成”还是“工程质量可靠”环境问题能慢慢修统计口径是硬伤。希望这篇笔记能帮你在 asp.net 油田计划生产系统上少踩几个坑把时间留给论文和正常睡眠。本文还有配套的精品资源点击获取
返回列表