
简介这是一套面向C# Winform初学者的SQL Server数据库操作实例围绕网络连接与本地连接两种模式逐步演示数据表的增删改查完整流程。资源共28个文件以.cs源代码、SQL查询脚本、配置文件、可执行程序及说明文档为主压缩包整体仅168KB轻量且便于快速下载使用。随包附带了Visual Studio解决方案、数据库脚本和文本说明内容涵盖连接字符串配置、ADO.NET核心组件、T-SQL语句、异常处理与事务管理等关键知识点并展示了如何将查询结果绑定到DataGridView等控件方便新手直观理解数据操作。通过对比两类连接方式读者可以清晰掌握服务器地址、认证信息等参数的设置方法。已有2673人学习下载适合正在入门Winform数据库开发、希望借助完整实例理解本地与远程数据库连接原理的读者参考。1. 先说清楚这份C# Winform SQL Server增删改查资源的底细有不少人拿到C# Winform的数据库项目第一反应是代码能打开但一运行就报连接失败甚至数据集里连表都没建。这份资源的好处在于它把两种典型连接方式都做进了同一个项目里——连接远程服务器的SQL Server以及连接本机的SQL Server实例增删改查四个操作全部跑通还附带一份可以直接执行的数据库脚本和连接配置说明。换句话说它既是源码包也是一个完整的新手教程。它解决的是入门阶段最卡人的问题连接字符串不知道怎么写、SQL Server装了但不知道表从哪来、程序跟数据库之间的连接到底是本地还是网络搞不清。适合刚学完C#语法、第一次碰Winform数据库开发的初学者也适合要交课程设计、或者刚入职接手老项目但从来没完整搭过环境的初级开发。下面我把这个项目从配置到代码一路拆开讲哪一步容易翻车也一并说清楚。2. 两种连接方式的取舍网络连接与本地连接的配置差异这份资源既然同时给了本地连接和网络连接说明作者是想让新手一次性分清这两个概念的。实际上二者在代码层面差别不大真正有差别的地方全在连接字符串Connection String和SQL Server的实例配置上。2.1 一个Data Source写错整个项目就卡死在这里先看连接字符串的构成。标准的SqlConnection连接字符串长这样string connStr Server.;DatabaseStudentDB;Integrated SecurityTrue;;这段代码里的Server.指的是本机默认实例。如果SQL Server是命名实例就要写成Server.\SQLEXPRESS如果是局域网里的另一台机器写成Server192.168.1.10,1433。这里的逗号是端口号默认端口号1433大多数情况下不用写但如果你装了多个实例端口就必须显式写。所谓本地连接和网络连接区别就在Server这一项本地连接指向.、localhost或.\实例名网络连接指向IP地址或机器名。Integrated SecurityTrue表示用Windows账号登录不需要用户名密码如果SQL Server用了混合认证模式就得写成User IDsa;Password123456;这是最常见的两种写法。项目里我一般会建议新手把两种写法都留一份在配置里因为本地开发和部署环境往往不一样。你本机用的是Windows验证服务器上可能是sa账号到时候切换连接方式只需要改配置文件不用动代码。2.2 App.config里放连接字符串别再把密码写死在代码里资源里的项目把连接字符串放在App.config文件中这个习惯很好。新手容易犯的毛病是把连接字符串硬编码到SqlConnection构造函数里结果换一台电脑就要改源码重新编译。放在配置文件里改完只需要重新生成或者直接替换exe目录下的配置文件即可。看一下典型的App.config内容?xml version1.0 encodingutf-8 ? configuration startup supportedRuntime versionv4.0 sku.NETFramework,Versionv4.6.1 / /startup connectionStrings add nameLocalConnection connectionStringServer.;DatabaseStudentDB;Integrated SecurityTrue; providerNameSystem.Data.SqlClient / add nameRemoteConnection connectionStringServer192.168.1.10,1433;DatabaseStudentDB;User IDsa;Passwordyourpassword; providerNameSystem.Data.SqlClient / /connectionStrings /configuration这样做的核心好处是代码里只需要通过ConfigurationManager.ConnectionStrings[LocalConnection].ConnectionString去取值环境变了只改配置。要注意的是引用System.Configuration程序集然后在using System.Configuration;之后才能用ConfigurationManager。很多新手在这里报错是因为项目没有添加这个程序集引用代码明明对编译却找不到类型。2.3 先测连接再写业务代码两行代码的测试探针拿到资源以后第一件事不是去看增删改查的界面而是先验证数据库通不通。我习惯在Form_Load里放一个测试按钮或者在窗体加载时就做一次连通性检测// 用配置名取连接字符串 string connStr ConfigurationManager.ConnectionStrings[LocalConnection].ConnectionString; // 创建连接对象并打开 using (SqlConnection conn new SqlConnection(connStr)) { try { conn.Open(); MessageBox.Show(连接成功当前数据库 conn.Database); } catch (Exception ex) { MessageBox.Show(连接失败: ex.Message); } }逻辑说明ConfigurationManager.ConnectionStrings[LocalConnection]取出之前配置好的连接字符串SqlConnection负责建立连接Open()才真正和SQL Server握手。using保证连接用完后自动释放这是避免连接泄漏的重要习惯。参数说明如果把Integrated SecurityTrue改成User IDsa;Password...Open()会走SQL Server账号认证此时就要确认SQL Server开启了混合登录模式这一块在第3章细讲。如果你在VS里测试时连接成功但发布到其他机器失败先检查目标机器能不能访问数据库服务器这是最常见的外部因素。3. 数据库脚本与配置把SQL Server端先立起来有相当一部分新手卡在代码没问题但库里没表。资源里附带的那份数据库查询语句文件就是用来解决这个问题的。3.1 建库建表脚本按顺序一条条执行别跳着跑脚本文件里的内容大概是这样以学生表为例CREATE DATABASE StudentDB; GO USE StudentDB; GO CREATE TABLE Student ( Id INT IDENTITY(1,1) PRIMARY KEY, StudentNo NVARCHAR(20) NOT NULL, Name NVARCHAR(50) NOT NULL, Gender NVARCHAR(2) DEFAULT 男, Age INT, Major NVARCHAR(50) ); GO INSERT INTO Student (StudentNo, Name, Gender, Age, Major) VALUES (2024001, 张伟, 男, 20, 计算机科学与技术);逻辑说明CREATE DATABASE建立数据库GO是批处理分隔符告诉SQL Server前面的语句已经结束可以提交执行。USE StudentDB切换当前数据库上下文保证CREATE TABLE建在正确的库里。IDENTITY(1,1)表示Id自增从1开始每次加1。NVARCHAR和NCHAR支持中文别用VARCHAR否则中文在特殊排序规则下容易乱码。最后的INSERT是给表里塞一条测试数据方便你界面写完就有东西可看。执行方式有两种在SSMSSQL Server Management Studio里新建查询粘贴进去执行或者用VS里的服务器资源管理器连接到本地实例后执行。对于初学者来说SSMS更直观因为能看到执行结果和错误行号。注意不同版本SQL Server的默认排序规则不太一样如果你执行脚本时报对象名无效或列名无效的错多半是语句顺序错了比如在USE StudentDB之前就去建表。还有一种情况是脚本文件是用记事本改过的编码不是UTF-8执行出来中文变成乱码。3.2 登录模式Windows验证连不上时改这一处SQL Server安装时默认登录认证方式是Windows身份验证模式。这种模式下你只能用Windows账号登录连接字符串里的User IDsa是无效的。而资源里的网络连接示例用的是SQL Server身份验证这就要把服务器的登录模式改成混合模式。在SSMS中右键服务器实例选择属性找到安全性勾选SQL Server和Windows身份验证模式然后执行这条SQLALTER LOGIN sa ENABLE; GO ALTER LOGIN sa WITH PASSWORD 123456; GO逻辑说明ALTER LOGIN sa ENABLE启用sa账号因为新版SQL Server中sa默认是禁用的。ALTER LOGIN sa WITH PASSWORD重置sa密码。改完之后还要在服务列表里重启SQL Server服务否则配置不生效。参数说明这里密码强度要求取决于服务器系统策略有些版本要求密码必须包含大小写、数字和特殊字符所以123456在Win10以上的系统里经常会执行失败。直接用sa账号也是安全风险如果是个人学习环境无所谓部署到公司服务器建议新建专属账号按最小权限授权。这是我在大量winform项目案例里看到的共性问题代码没错、SQL Server也装了就是登录模式不对导致报用户 sa 登录失败。这个坑在资源和网络讨论里反复出现值得你花五分钟提前确认。3.3 数据库配置落地方案从装SQL到连上的三步流程如果你连SQL Server都还没装完先按照官方安装包走一路默认选项即可。需要注意的是功能选择里务必勾选SQL Server数据库引擎服务和客户端工具。很多新手安装完发现SSMS打不开就是漏了管理工具组件。安装完成后按照这个顺序做打开SSMS用Windows验证登录到.\SQLEXPRESS或默认实例。执行建库建表脚本。确认登录模式为混合模式并启用sa账号。回到Winform项目修改App.config里的连接字符串。这套流程我每次接手新环境都走一遍顺序不能反。先建库再配账号最后测连接好处是你排查问题时能明确知道是SQL Server没起来还是连接字符串写错。几步分开看失败的环节一眼就能定位。4. 增删改查的代码实现DataGridView绑定与参数化SQL执行数据库通了接下来就是项目里最核心的增删改查界面。资源里的界面是一个典型的Winform布局顶部是输入框和按钮中间是DataGridView表格展示查询结果。整个实现思路在初学者看来会比较直接但有几个细节直接影响稳定性。4.1 查询DataGridView绑定DataTable三行代码出结果查询按钮的点击事件代码逻辑是这样的private void btnQuery_Click(object sender, EventArgs e) { string connStr ConfigurationManager.ConnectionStrings[LocalConnection].ConnectionString; string sql SELECT Id, StudentNo, Name, Gender, Age, Major FROM Student; using (SqlConnection conn new SqlConnection(connStr)) { SqlDataAdapter adapter new SqlDataAdapter(sql, conn); DataTable dt new DataTable(); adapter.Fill(dt); dataGridView1.DataSource dt; } }逻辑说明SqlDataAdapter在这里充当桥的角色它内部自己打开连接、执行SqlCommand、把结果填充到DataTable然后关闭连接。Fill(dt)执行之后数据就脱离数据库独立存在所以可以在using块结束后继续显示。最后把DataTable直接赋给dataGridView1.DataSource表格自动生成列并填充数据。参数说明这段代码里SQL是固定的。如果查询条件里有用户输入的关键字不要拼字符串改用下面的方式string sql SELECT Id, StudentNo, Name FROM Student WHERE Major LIKE major; SqlCommand cmd new SqlCommand(sql, conn); cmd.Parameters.AddWithValue(major, % txtMajor.Text.Trim() %);AddWithValue会自动处理单引号、中文、特殊字符的问题防止SQL注入。血泪经验是永远不要用 txtMajor.Text 去拼SQL一条用户输入包含; DROP TABLE Student; --就能把表删了。这个套路在面试和课程设计答辩中经常被老师追问用参数化作答才是完整方案。4.2 插入、更新、删除ExecuteNonQuery统一处理插入按钮的写法string connStr ConfigurationManager.ConnectionStrings[LocalConnection].ConnectionString; string sql INSERT INTO Student (StudentNo, Name, Gender, Age, Major) VALUES (no, name, gender, age, major); using (SqlConnection conn new SqlConnection(connStr)) { conn.Open(); SqlCommand cmd new SqlCommand(sql, conn); cmd.Parameters.AddWithValue(no, txtStudentNo.Text.Trim()); cmd.Parameters.AddWithValue(name, txtName.Text.Trim()); cmd.Parameters.AddWithValue(gender, cboGender.Text); cmd.Parameters.AddWithValue(age, Convert.ToInt32(txtAge.Text.Trim())); cmd.Parameters.AddWithValue(major, txtMajor.Text.Trim()); int rows cmd.ExecuteNonQuery(); MessageBox.Show(rows 0 ? 添加成功 : 添加失败); }逻辑说明ExecuteNonQuery用于执行不返回结果集的SQL语句返回受影响的行数。这里rows等于1说明插进去一条记录。更新和删除的代码结构完全一样只是SQL语句换成UPDATE和DELETE// 更新 string sql UPDATE Student SET Namename, Majormajor WHERE Idid; cmd.Parameters.AddWithValue(id, selectedId); // 删除 string sql DELETE FROM Student WHERE Idid;id这里有个细节更新和删除应该用主键Id来定位而不是用学号StudentNo。因为学号理论上唯一但实际录入时可能有重复只有自增主键Id才能精确锁定一行。关于Winform控件这里TextBox、ComboBox、Button、DataGridView是四个核心控件。DataGridView的属性里SelectionMode建议设为FullRowSelect这样用户点任意单元格都能选中整行ReadOnly设为True防止用户直接在表格里改数据造成界面和数据库不一致。4.3 选中行回显让修改操作变成点一下就能改界面里修改按钮的常用做法用户点表格某行该行的字段回填到上方文本框然后直接改内容再点更新按钮。private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e) { if (e.RowIndex 0) return; DataGridViewRow row dataGridView1.Rows[e.RowIndex]; selectedId Convert.ToInt32(row.Cells[Id].Value); txtStudentNo.Text row.Cells[StudentNo].Value.ToString(); txtName.Text row.Cells[Name].Value.ToString(); cboGender.Text row.Cells[Gender].Value.ToString(); txtAge.Text row.Cells[Age].Value.ToString(); txtMajor.Text row.Cells[Major].Value.ToString(); }逻辑说明e.RowIndex是用户点击行的索引row.Cells[列名].Value取值后赋给窗体控件。selectedId是一个窗体级变量供更新和删除按钮使用。参数说明这里txtAge.Text是字符串数据库中Age列是int类型如果文本框内容为空Convert.ToInt32会抛异常。实际项目中一般会加校验比如int.TryParse(txtAge.Text.Trim(), out age)转换失败就提示用户输入数字。这个是最容易被测试人员点出来的小毛病也是你在演示时最容易翻车的输入场景。连接和命令对象的释放同样重要。每个按钮事件里都用了using确保SqlConnection和SqlCommand用完后被Dispose。如果你不这么做连续点十几次查询就会出现连接池超时的报错这就是为什么有些Winform程序用着用着突然卡死的原因。5. 避坑记录新手最容易踩的四个数据库连接坑第2章到第4章把路径理顺了这章专门记录我在拆这类项目时遇到过的翻车现场以及对应的原因和解决办法。每一条都有具体现象你可以对照排查。5.1 现象连接字符串写Server.\SQLEXPRESS报Network-related InstanceNotFound这是在我拆过的winform项目案例里出现频率最高的问题。现象是运行时报错A network-related or instance-specific error occurred while establishing a connection to SQL Server看起来好像是网络问题实际上跟网络没关系。原因有两类一是SQL Server服务没有启动二是实例名字写错了。很多人装了SQL Server但没注意实例名默认为MSSQLSERVER连接字符串应该写Server.或Serverlocalhost而SQLEXPRESS是Express版的实例名如果你装的是企业版或开发版这个实例名根本不存在。解决打开服务窗口找到SQL Server (MSSQLSERVER)或SQL Server (SQLEXPRESS)确认状态是正在运行。然后在命令行执行SqlLocalDB info查看有哪些实例用实际实例名替换连接字符串中的Server部分。5.2 现象VS里调试一切正常发布到别的机器上连不上数据库这是典型的开发环境依赖。本地调试时Server.指向的是你开发机上的SQL Server实例发布到另一台机器后Server.指向的是那台机器本地的实例但如果那台机器根本没装SQL Server自然就连接失败。原因把数据库连接写死在本地实例上部署时又没有同步更新配置文件。对于课程设计这种单人使用的场景还好多人协作时就会出现我的电脑能跑你的电脑不行的尴尬局面。解决如果数据库和程序在同一台机器目标机器必须安装SQL Server并导入脚本如果是多人共用数据库连接字符串应改成Server服务器IP,端口;User IDsa;Password...并确保服务器防火墙放行1433端口。我一般会在这个项目里同时保留两份配置本地调试用LocalConnection部署时切到RemoteConnection这样切换成本最低。5.3 现象数据全出来了但中文字符变成或者乱码原因有两层建库时排序规则Collation不是中文相关规则默认的SQL_Latin1_General_CP1_CI_AS对中文支持不友好或者使用VARCHAR类型存中文。另一种情况是执行脚本时文件编码不对比如用记事本另存为GBK编码SQL语句里的中文字符串传进库时已经变了。解决建表时统一用NVARCHAR建库时指定中文排序规则脚本开头加一句CREATE DATABASE StudentDB COLLATE Chinese_PRC_CI_AS;Chinese_PRC_CI_AS是中国大陆默认的简体中文排序规则CI表示不区分大小写AS表示区分重音。执行脚本前把文件另存为带有BOM的UTF-8编码SSMS才能正确识别。5.4 现象程序运行一段时间后数据库操作越来越慢最后报连接池超时这个坑在长时间开着窗体反复点增删改查时最容易出现。报错内容类似Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool。原因每次连接没有关闭。虽然SqlConnection在using块结束后会自动关闭但如果你在代码里用了手动conn.Open()而没有conn.Close()连接对象被垃圾回收时才会真正释放之前一直占用连接池中的名额。连接池默认最大连接数是100到了上限就排队等待超时。解决所有SqlConnection一律用using包裹示例代码每一条都这么写。另外确认每一条分支路径上都没有提前return而不释放连接的情况。如果你觉得每次写using太啰嗦下一章封装的帮助类就是干这件事的。5.5 现象删除按钮点了没反应但也不报错这里多半是ExecuteNonQuery返回了0行。原因删除条件写错了比如用StudentNo匹配但文本框里的学号和数据库不一致或者Id列没有赋值selectedId是0。解决CellClick回显时把Id存到窗体级变量删除时用WHERE Idid。如果还是0行用MessageBox.Show先打印一下执行的行数再检查Sql语句在SSMS里能不能执行快速定位是数据问题还是代码问题。6. 验证方法与进阶把连接和代码包成一个通用帮助类前面每段代码都完整但重复每个按钮都要写一遍using SqlConnection、using SqlCommand非常繁琐。资源里如果结构清晰你可以顺手做一个SqlHelper类把连接的创建、打开、执行查询、执行非查询统一收口这也是我从这个项目里收获最大的一件事。public class SqlHelper { private static readonly string connStr ConfigurationManager.ConnectionStrings[LocalConnection].ConnectionString; public static DataTable ExecuteQuery(string sql, params SqlParameter[] parameters) { using (SqlConnection conn new SqlConnection(connStr)) using (SqlCommand cmd new SqlCommand(sql, conn)) { if (parameters ! null) cmd.Parameters.AddRange(parameters); SqlDataAdapter adapter new SqlDataAdapter(cmd); DataTable dt new DataTable(); adapter.Fill(dt); return dt; } } public static int ExecuteNonQuery(string sql, params SqlParameter[] parameters) { using (SqlConnection conn new SqlConnection(connStr)) { conn.Open(); using (SqlCommand cmd new SqlCommand(sql, conn)) { if (parameters ! null) cmd.Parameters.AddRange(parameters); return cmd.ExecuteNonQuery(); } } } }这个类的接入成本很低。原来的查询方法SqlDataAdapter adapter new SqlDataAdapter(sql, conn)直接换成DataTable dt SqlHelper.ExecuteQuery(sql)插入更新删除换成int rows SqlHelper.ExecuteNonQuery(sql, parameters)。params关键字的用法是允许调用方传任意多个SqlParameter也可以只传SQL不传参数灵活性刚好覆盖增删改查的所有场景。封装完成后有一个值得做的验证动作连续点击查询按钮50次同时打开SQL Server的活动监视器观察连接数是否稳定。如果连接数一直增长说明你的连接没有释放如果稳定在一个固定值说明using生效了。用这个项目当实验场比只看代码更有说服力。替换表名和字段后这个帮助类可以直接套用到别的业务表上。比如把Student换成Course只需要改SQL语句不用再改任何连接代码。这也是我建议你在这份资源基础上做的第一件小事把重复代码收拢让项目结构更接近真实生产环境。从那以后我每次拿到别人的Winform数据库项目不管对方说配置都好了还是直接能跑都强制走一遍完整流程先看App.config连接字符串再建库导脚本接着测试登录模式最后打开界面验证增删改查。过程听起来繁琐但它能把绝大多数代码玄学问题排除掉剩下的才是真正的程序Bug。希望帮到你。本文还有配套的精品资源点击获取