☰
C#合同管理系统源码解析:数据库还原、连接串配置与到期提醒实现
2026/10/1 16:35:45 网站建设 项目流程

简介:一套基于C#与SQL Server数据库开发的合同管理系统完整源码包,主要面向C#初学者、软件课程设计及毕业设计参考。系统围绕客户、项目、合同信息及合同执行控制等模块设计,将各功能模块相互连接组成合同数据管理流程,明确区分管理员与普通用户权限:管理员可维护客户、项目、合同及执行控制,普通用户可查询相关明细,覆盖管理系统的典型操作路径。压缩包共123个文件,大小约2.82MB,以cs源码、resx/resources资源文件、config配置文件、sln/csproj工程文件为主体,另含mdf/ldf数据库文件和exe可执行程序,便于附加数据库后调试运行。当前已有153人学习下载,可帮助读者快速理解基于C#的WinForm项目结构、数据库交互方式以及合同管理业务的模块划分;完整工程文件与数据库脚本亦可作为课程设计报告编写或二次开发的直接基础,适合在Visual Studio中结合SQL Server进行功能扩展。

1. 拿到“C# 合同管理系统源码+数据库”包:先想清楚这三件事

拿到“基于C#的合同管理系统(源码+数据库).zip”这个包,大多数人的第一反应是解压、打开、双击 exe 看界面。我建议反过来:先想清楚你要读代码、改代码,还是只想在内部环境跑起来用。这套包通常由一个 Visual Studio 解决方案和一个 SQL Server 数据库备份组成,解决的是合同台账散落在 Excel、到期没人提醒的问题,适合正在学 C# 想啃一个完整项目的人,也适合需要快速交付内网管理工具的一线开发者。真正值钱的点不是增删改查那几段代码,而是数据库表结构和到期提醒的边界处理——这两处最容易被新手改坏,也最值得抄。下面的内容按“拆包→跑通→精读→避坑→验证”的顺序推进。

2. 拆包与架构:先看懂压缩包里有什么,再动手改代码

拿到这类 zip,我不会直接解压到桌面,而是建一个干净的工作目录,比如D:\Work\Contract01,把压缩包完整解压进去,然后按优先级检查四类东西:解决方案文件、项目文件、配置文件、数据库文件。这一步能帮你判断这个包值不值得继续投入,也决定了后面用哪种方式还原数据库。

2.1 文件清单:.sln、.csproj、App.config、数据库文件各管什么

文件/目录常见形态动手前先确认什么
解决方案ContractManage.sln用哪个 VS 版本打开,命令行用什么编译
项目文件ContractManage.csproj目标框架版本,引用了哪些第三方 DLL
配置文件App.config/web.config数据库连接串是否唯一入口
数据库ContractDB.bak或.mdf还原方式,备份版本,日志文件是否配套
说明文档使用说明.txt / 设计文档.doc默认管理员账号、数据库还原步骤

先看.sln。用记事本打开,前几行会写着 Visual Studio 版本号,比如 14.0 对应 VS2015,17.0 对应 VS2022。版本比你本机高不用慌,用高版本 VS 打开低版本解决方案通常没问题,反过来就会报“不受支持的项目类型”。我一般会跳过 .sln,直接看 .csproj 里的TargetFrameworkVersion,这个字段决定你能不能编译过。

再看App.config。连接串是这套系统的命门,但老系统喜欢把连接串直接写在代码里,比如某个窗体文件里直接new SqlConnection("server=.;...")。你拿到包后在源码目录里搜索conn、connection、Server=,把所有出现连接串的地方都找出来,确认是不是只有配置文件一处。后面改数据库实例只需要动这一处,才是好结构。

数据库文件是灵魂。.bak是完整备份,.mdf是分离后的数据文件。先看文件大小和修改时间,几十 MB 的 bak 通常是真数据,几 KB 的就要警惕——很可能是作者清空数据后备份的空壳子。空结构也能用,但你要接受没有测试数据的调试体验,所有列表页打开都是空白,出了问题很难判断是查询问题还是数据问题。

2.2 为什么这类系统默认是 WinForms + SQL Server:三种连接写法对比

这类源码包十有八九是 WinForms + SQL Server,原因很直白:System.Data.SqlClient是 .NET Framework 自带的,不需要额外装驱动;WinForms 拖拽控件就能出界面,学习成本最低;毕业设计和中小企业内部系统都偏爱这种组合。你要是打开源码发现用的是 Access 或 SQLite,也别意外,重点看连接串怎么配。

技术组合连接串关键特征适合场景
WinForms + SQL ServerData Source=+Initial Catalog=单机或局域网,数据量大,C# 生态最顺
WinForms + AccessProvider=Microsoft.ACE.OLEDB.12.0单机免安装,数据量小,并发弱
WPF / ASP.NET + SQLiteData Source=C:\xxx.db跨平台或嵌入式,需要自己装驱动

区分方法很简单:App.config里connectionString开头是Provider=则是 Access;Data Source=后面跟的是数据库文件路径而不是服务器名,则是 SQLite 或 LocalDB;Data Source=.或本机 IP,Initial Catalog=库名,就是 SQL Server。注意 LocalDB 也很常见,连接串形如Data Source=(LocalDB)\MSSQLLocalDB,它本质上还是 SQL Server,但数据库文件是 .mdf,启动当前用户实例。调试方便,但换台机器容易连不上。

我个人的建议:如果要长期维护,把它改成标准 SQL Server 实例连接最省心;如果只是想看界面效果,先用 LocalDB 跑通也行,但上线前一定要切回正常实例。LocalDB 的服务是跟着当前 Windows 用户走的,换账号登录系统,应用就连不上了,这类问题排查起来非常迷惑。

2.3 三张核心表的建表逻辑:合同主表、系统用户表、到期提醒视图

几乎所有合同管理系统都绕不开这三样:一个放合同主体的主表,一个放系统登录账号的用户表,一个基于主表的到期提醒查询。下面这套建表语句是按常见做法整理的,你在源码包里看到的表结构可能略有不同,但核心字段跑不出这些。

-- 合同主表 CREATE TABLE dbo.ContractMain ( ContractId INT IDENTITY(1,1) PRIMARY KEY, ContractNo NVARCHAR(50) NOT NULL UNIQUE, CustomerName NVARCHAR(100) NOT NULL, ContractAmount DECIMAL(18,2) NOT NULL DEFAULT 0, SignDate DATETIME NULL, DueDate DATETIME NULL, ArchiveFlag TINYINT NOT NULL DEFAULT 0, Remark NVARCHAR(500) NULL ); -- 系统用户表 CREATE TABLE dbo.SysUser ( UserId INT IDENTITY(1,1) PRIMARY KEY, UserName NVARCHAR(50) NOT NULL UNIQUE, UserPwd NVARCHAR(128) NOT NULL, IsAdmin TINYINT NOT NULL DEFAULT 0 ); -- 到期提醒视图(30天内到期) CREATE VIEW dbo.vDueRemind AS SELECT ContractNo, CustomerName, DueDate FROM dbo.ContractMain WHERE ArchiveFlag = 0 AND DueDate IS NOT NULL AND DueDate >= CAST(GETDATE() AS DATE) AND DueDate < DATEADD(day, 31, CAST(GETDATE() AS DATE));

第一段里最关键的是两个约束:ContractNo加 UNIQUE,防止同一合同号重复登记;ContractAmount用DECIMAL(18,2),不要用 FLOAT,二进制浮点存金额会出现 0.1+0.2 不等于 0.3 这类精度问题,做财务报表时会被审计盯上。

DueDate允许 NULL 是个容易被忽略的设计。有些合同只签了起始日期没有约定到期日,如果建表时把DueDate设成 NOT NULL,登记时就得填假日期,后面的到期提醒会误报。NULL 不是脏数据,是业务真实状态,查询时专门用IS NOT NULL过滤。

SysUser表里注意密码字段。老代码常见的是明文 varchar,能跑但不安全。你接手后第一件事不是改界面,而是把密码改成哈希存储。SHA256 或 BCrypt 都行,关键是登录代码里的校验逻辑要同步改,否则所有老账号会登不进去。以前我吃过这个亏,改完密码策略后同事的账号全废了,被骂了一下午。

到期提醒视图的本质就是一条 WHERE 条件带日期窗口的 SELECT。窗口的写法很重要,常见错误是把到期日等于今天那条漏掉,后面第 4 章会单独讲这类边界条件。

3. 把系统跑起来:还原数据库、改连接串、编译到双击登录

跑通这套系统的完整路径是三段:把数据库弄到本机,把连接串指到本机,然后编译。这三段每一步都有各自最容易翻车的地方,下面的操作顺序是我验证过最稳的,按顺序走能少踩一半坑。

3.1 还原 .bak 与附加 .mdf:两条可复制的 SQL 路径

拿到.bak,优先用RESTORE而不是 SSMS 图形界面。图形界面在 MOVE 路径上经常自作主张,命令行反而可控。先查备份文件内部包含哪些逻辑文件:

RESTORE FILELISTONLY FROM DISK = N'C:\Work\ContractDB.bak';

输出结果里LogicalName列就是后面 MOVE 要用到的两个名字,一个是数据文件,一个是日志文件,复制下来备用。然后执行还原:

RESTORE DATABASE ContractDB FROM DISK = N'C:\Work\ContractDB.bak' WITH REPLACE, MOVE 'ContractDB_Data' TO N'C:\Work\ContractDB.mdf', MOVE 'ContractDB_Log' TO N'C:\Work\ContractDB_log.ldf';

还原成功的前提有两个:目标路径所在目录有权限,以及WITH REPLACE允许覆盖同名数据库。如果报“目录查找失败”,九成是 LogicalName 抄错了,回上一步重新查一次,不要凭记忆猜名字。

如果你拿到的是.mdf而不是.bak,用附加方式:

USE master; GO CREATE DATABASE ContractDB ON (FILENAME = N'C:\Work\ContractDB.mdf') FOR ATTACH;

附加比还原轻量,但有个隐藏坑:.mdf和.ldf必须配套。有些压缩包只放了.mdf没放日志文件,附加时会报缺少日志,或者自动重建日志失败。我一般建议拿到.mdf的先确认有没有配套的.ldf,没有的话试试FOR ATTACH_REBUILD_LOG,能救一部分情况。

注意:数据库文件不要放在 C 盘根目录或桌面,SQL Server 服务账户对这些位置的写权限经常出问题。统一放D:\SQLData\这类专用目录,后面排查问题会省很多事。

3.2 连接串的四个必改参数:实例名、数据库名、登录方式、超时

连接串是这套系统跑不起来的头号原因。App.config里常见写法是:

<connectionStrings> <add name="ContractDbConnection" connectionString="Data Source=.;Initial Catalog=ContractDB;User ID=sa;Password=YourPwd;Encrypt=False;TrustServerCertificate=True;Connection Timeout=5;" providerName="System.Data.SqlClient" /> </connectionStrings>

第一个参数Data Source,点是本机默认实例;如果你的 SQL Server 是命名实例,要写机器名\SQLEXPRESS,不要写localhost\SQLEXPRESS,localhost 有时解析出 IPv6 导致连不上。

第二个参数Initial Catalog必须和实际数据库名一致。还原的时候你给数据库起的名字叫 ContractDB,这里就写 ContractDB。拼写错误会报一些看着完全不相干的信息,比如找不到服务器或登录失败,先别怀疑网络,回来看一眼库名。

第三个参数是登录方式。本地调试建议用Integrated Security=True,省去账号密码的权限问题;但如果源码里大量代码都在业务层拿同一个连接串创建连接,改成集成认证一般就够。用 sa 账号时注意别把密码写死到 Git 仓库,那等于把数据库门钥匙贴在门上。

第四个参数Connection Timeout=5。默认 15 秒在开发机上没什么感觉,但在网络不通时会让你干等。设成 5 秒,连不上就快速失败,错误日志里能直接看到是谁在尝试连接。这个参数不会影响正常连接性能,纯粹是故障时的体感优化。

关于Encrypt=False,这是个玄学项。.NET Framework 4.7.2 以上的 SqlClient 默认请求加密,老 SQL Server 2016 之前不支持,于是两边一言不合就断连。你要是看到报错内容含 SSL 或证书,直接把Encrypt设成 False、TrustServerCertificate设成 True,绝大多数能救回来。

连接池默认开着,这个系统并发不高,不需要调 Min Pool Size,保持默认就行。真正的坑是业务代码里频繁开关连接但没有 using,池满了会报超时。回头在代码里补 using 比调池参数更有意义,且这个系统里凡是写了这一步的代码基本都是采用同样模式,改起来不难。

3.3 从 msbuild 到双击登录:目标框架缺失时的处理顺序

VS 用户直接双击.sln就能编译;但如果你在命令行环境快速验证,用 msbuild 更直接:

msbuild ContractManage.sln /p:Configuration=Release /p:Platform="Any CPU"

第一次编译大概率遇到两个问题。第一个是目标框架不存在:csproj 里写着 v4.5 或 v4.6.2,而你机器只装了 .NET 6/8。这时不要去装一个老年框架,直接打开 csproj 把TargetFrameworkVersion改高,比如改成v4.7.2。注意改完要重启 VS。

第二个问题是缺引用。老项目里经常引用一个本机某路径下的 DLL,比如第三方控件或报表组件,你机器上没有。处理顺序是:先搜 csproj 里的HintPath,看看引用的是哪个目录;再到项目里删除那条引用,用 NuGet 重新装一个等价包。如果作者用的是第三方收费控件而你没授权,这条路走不通,那就只能绕开对应模块,这是源码包的边界之一。

编译通过后,直接运行bin\Release下的 exe。窗体能弹出来、点登录不报数据库连接异常,才算真的跑起来了。到这里,你手里的源码才从压缩包变成一个可以开始改的系统。

4. 源码精读:登录校验、增删改查、到期提醒,三处最值得改的代码

跑起来只是第一步,真正要投入的是把源码读明白。这套系统里最常被改的三块是登录校验、合同登记和到期提醒。三块改起来都不难,但都有各自的边界,改错一个条件,功能就静默失效。

4.1 登录校验:把拼 SQL 改成参数化,避免注入

老源码里常见的反面教材是把文本框内容直接拼进 SQL。登录框是 SQL 注入重灾区,输入' or '1'='1直接绕过校验,这是最典型的低级漏洞。改成参数化只需要把 SQL 字符串里的值换成 @ 占位符,再用 Parameters 集合传值,实质是让驱动把输入当数据处理而不是当 SQL 执行:

using (var conn = new SqlConnection(cs)) using (var cmd = new SqlCommand( "SELECT COUNT(1) FROM SysUser WHERE UserName=@u AND UserPwd=@p", conn)) { cmd.Parameters.AddWithValue("@u", userName.Text.Trim()); cmd.Parameters.AddWithValue("@p", pwd.Text); conn.Open(); int n = (int)cmd.ExecuteScalar(); if (n == 1) { // 登录成功,打开主窗体 } else { MessageBox.Show("用户名或密码错误"); } }

AddWithValue在老 .NET 代码里很常见,但它有两个问题:一是对 NVARCHAR 列会默认推断类型,数据量大时索引失效;二是 SQL Server 可能把参数类型推断成 NVARCHAR 导致隐式转换,拖慢查询。宁可多写两行SqlParameter指定 DbType,也别图省事。

密码存储也顺带说一句。就算这段代码只在内网跑,密码明文入库也是隐患。改成 SHA256 做哈希存储,登录校验的时候把输入的密码哈希后和库里比对。改造前先把老账号的密码用程序批量哈希一遍,否则全员进不去,这个后果我当年替别人扛过。

4.2 合同登记与编辑:DataGridView 绑定和字段防呆

WinForms 时代的标准写法是 DataTable 加 DataGridView 绑定,查询用适配器把结果倒进 DataTable,界面只管展示。这套写法的好处是代码少,坏处是列标题和宽度需要手动调,且 DataGridView 默认会把所有列都显示出来:

DataTable dt = new DataTable(); using (SqlDataAdapter da = new SqlDataAdapter( "SELECT ContractId, ContractNo, CustomerName, ContractAmount, DueDate " + "FROM ContractMain WHERE ArchiveFlag=0", cs)) { da.Fill(dt); } dataGridView1.DataSource = dt; dataGridView1.Columns["ContractId"].Visible = false;

保存时有两种路子。简单场景用SqlCommandBuilder自动生成 Insert/Update/Delete 命令,代码只有三行;但我不建议在合同这种要留痕的数据上这么做——自动生成命令没有业务校验,用户把金额改成负数也存得进去。手动写 Update 时,防呆的重点是让非法输入在进 SQL 之前死掉:

if (!DateTime.TryParse(txtDueDate.Text, out DateTime due)) { MessageBox.Show("到期日期格式不正确,示例:2025-06-30"); return; } if (!decimal.TryParse(txtAmount.Text, out decimal amount) || amount <= 0) { MessageBox.Show("合同金额必须是大于 0 的数字"); return; }

日期格式错误、金额超出范围、必填项为空,都在界面层拦截,不要等数据库报错。为什么?数据库报的错很难看懂,比如“从字符串转换日期和/或时间失败”,用户一脸懵,IT 也难排查。界面层拦一道,错误提示可以直接写成业务语言。

另一个 WinForms 老坑是DataGridView.CurrentRow为 null。用户点了行头而不是单元格时,CurrentRow 可能取到 null,代码里取Cells["ContractId"].Value直接抛 NullReferenceException。取值前先判断CurrentRow != null,这是血泪经验换来的。

4.3 到期提醒:把“快到期”写对,别忽略三个边界

到期提醒是合同管理系统最有存在感的功能,也是改坏率最高的地方。下面这条 SQL 是典型的 30 天到期提醒查询:

SELECT ContractNo, CustomerName, DueDate FROM ContractMain WHERE ArchiveFlag = 0 AND DueDate IS NOT NULL AND DueDate >= @today AND DueDate < DATEADD(day, 31, @today) ORDER BY DueDate;

这段查询的边界都在 WHERE 里。第一个边界是到期日等于今天的合同要算进去,所以用>= @today而不是> @today,否则当天到期提示不出来。第二个边界是 30 天窗口要覆盖完整 30 天,用DueDate < DATEADD(day, 31, @today),把今天这一天的窗口拉开,不然怎么算都只有 29 天。

第三个边界是ArchiveFlag = 0。已经归档的合同,无论到期与否都不应该出现在提醒里。这个条件在列表页查询里很常见,但在提醒 SQL 里经常被漏掉,结果就是历史合同反复提醒,使用者两三天后就麻木了,真正该提醒的反而被忽略。

空值问题同样在提醒里。DueDate是 NULL 表示没有约定到期日,它不应该出现在任何提醒里,也不要试图把 NULL 换算成某个日期去比较——NULL 在 SQL 里就是未知,任何比较运算结果都是 NULL,用IS NOT NULL过滤是最干净的写法。

如果想让提醒有优先级,比如 3 天内到期的高亮置顶,可以在 ORDER BY 里加 CASE:

ORDER BY CASE WHEN DueDate < DATEADD(day, 3, @today) THEN 0 ELSE 1 END, DueDate;

这样查询结果前三天的排前面,后面按到期日升序。界面上也可以按这个结果做红色高亮,数据层把优先级标计算好,界面只负责画样式,两边不耦合。

5. 避坑手记:从“能打开”到“能跑”的六类经典翻车现场

这套源码从解压到稳定运行,最大的阻碍不是业务逻辑,是环境差异。以下六类翻车现场按发生频率排序,每条都是同一个套路:现象、原因、解决。你在自己的机器上照着排查,八成能少走半天弯路。

5.1 数据库还原失败:先看版本,再动 MOVE

坑 1:还原时报“数据库备份集是旧版”或“不是有效的备份文件”。

现象:SSMS 里选备份文件点确定,弹窗报错,或者 RESTORE 命令执行到一半失败。

原因:备份来自更高版本 SQL Server,低版本实例读不了高版本备份,这是 SQL Server 的向下兼容限制。偶尔是 zip 解压不完整,bak 文件被截断。

解决:先用HEADERONLY看版本,确认本机实例能接受:

RESTORE HEADERONLY FROM DISK = N'C:\Work\ContractDB.bak';

输出里有DatabaseVersion列。如果版本比本机高,两个选择:装一个同版本实例,或者在高版本实例上还原后导出 bacpac 再导入低版本。后者麻烦但不用动环境,适合偶尔一次的场景。

坑 2:还原到一半报“目录查找失败”。

现象:进度条到 80% 才失败,错误指向一个不存在的路径。

原因:bak 内部记录的是打包人的数据文件路径,MOVE 目标路径没写对。

解决:先用FILELISTONLY查出备份内的 LogicalName 和 PhysicalName,MOVE 的第二个参数写本机存在的目录,文件名随意但后缀要对应。注意目录要有 SQL Server 服务账户的写权限,放 D 盘专用目录比放 C 盘系统目录稳得多。

5.2 登录即报错:连接串、SQL Server 服务和中文乱码

坑 3:一进系统就弹“建立到服务器的连接时发生错误”。

现象:窗体能打开,一点登录就报错,错误信息里有“SQL Server 不存在或拒绝访问”。

原因:连接串指向的实例名和你本机的实例名不一致;或者 SQL Server 服务没启动;或者 sa 账号被禁用。

解决:先用 sqlcmd 快速验证连通性,再改连接串:

sqlcmd -S . -U sa -P YourPwd -d ContractDB -Q "SELECT 1"

sqlcmd 能通而程序不能通,说明是配置问题;sqlcmd 也不通,说明服务没起来或密码错了。本地开发建议直接改Integrated Security=True,绕开账号密码这一层,但要注意发布到服务器时改回标准账号登录。

坑 4:数据库里是中文,界面上显示成???。

现象:合同名称、客户名称在 DataGridView 里全是问号。

原因:列类型是varchar而不是nvarchar,插入时中文被转成 ? 存储;或者从备份还原时排序规则不一致。

解决:优先把列改成nvarchar,这不是治标是治本:

ALTER TABLE dbo.ContractMain ALTER COLUMN CustomerName NVARCHAR(100) NOT NULL;

改完重跑一次录入,新数据正常。老数据救不回来,只能重录或从源库导出。这个坑的教训是建表时凡是可能存中文的列,从一开始就用nvarchar,别图省那一点空间。

5.3 编译与编码:目标框架、缺失引用和文件编码

坑 5:编译报 CS0246 找不到System.Data.SqlClient命名空间。

现象:代码里using System.Data.SqlClient;下面全是红波浪线,msbuild 也失败。

原因:项目目标框架和代码不匹配,可能是 .NET 6/8 项目里引用了老命名空间;或者项目自带 NuGet 包没有还原。

解决:先看 csproj 的TargetFramework字段。如果是net6.0之类,改成 .NET Framework 老项目最省事:

<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>

如果不想降级,去 NuGet 安装Microsoft.Data.SqlClient,但代码里所有SqlConnection要相应换成Microsoft.Data.SqlClient的命名空间,改动量更大。老源码包优先走第一条路,改动最小、风险最低。

坑 6:编译时提示无法解析某个 DLL 的引用。

现象:错误列表里出现某个 DLL 名称,说找不到或版本冲突。

原因:作者在开发机上用了第三方控件,引用路径写在 csproj 的HintPath里,你机器上没这个目录。

解决:右键那条引用,删除,然后用 NuGet 重新安装等价包。如果是商业控件没有授权,这条路走不通,那就退一步,把用到这个控件的窗体从编译里排除或临时注释掉。这是源码包的硬边界,不值得花钱硬解,绕过即可。

6. 交付验证与两处小改造:让这套源码从合格到好用

跑通、避完坑之后,还要做两件事才算真正接手这套源码:一次说得出口的验证,一次能证明你读懂结构的改造。

6.1 一条 SQL 完成上线前验收

不管界面做得多漂亮,交付前我只认一条 SQL 的结果:

SELECT COUNT(1) AS TotalContracts, SUM(ContractAmount) AS TotalAmount, SUM(CASE WHEN DueDate >= CAST(GETDATE() AS DATE) AND DueDate < DATEADD(day, 31, CAST(GETDATE() AS DATE)) THEN 1 ELSE 0 END) AS DueIn30Days FROM dbo.ContractMain WHERE ArchiveFlag = 0;

这条 SQL 回答三个问题:一共录了多少合同、总金额是多少、未来 30 天有多少合同到期。上线前在数据库里跑一遍,再和界面列表的合计对一下。两个数字对不上,说明查询条件写错了或者界面过滤条件漏了,这时候不要去调界面,先回查 WHERE 条件。我见过太多系统上线后才发现列表显示 100 万而报表合计 80 万,最后查出是界面端多了一个默认过滤条件没同步。

6.2 加一个“负责人”字段:从数据库到界面只动三处

一次典型的小改造是给合同主表加一个负责人字段。第一步加列:

ALTER TABLE dbo.ContractMain ADD OwnerName NVARCHAR(50) NULL;

第二步在主查询的 SELECT 列里加上OwnerName,DataGridView 会自动显示新列,第三步在登记窗体的文本框上绑定同一列。如果保存走的是SqlCommandBuilder,自动生成的 Update 命令会带上这个新列,连存储过程都不用改。三步做完,重新编译运行,新字段就能正常读写了。

我接手这类源码包的习惯是先还原数据库,再用那条验收 SQL 跑一遍,确认数字对得上才去动源码。每加一个字段都保留一条ALTER TABLE备份语句,哪天改坏了,这是唯一的后悔药。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询