C#&SQL Server基于三层架构实现增删改查

简介: C#&SQL Server基于三层架构实现增删改查

框架一览


先来看看C#和SQL Server的整个框架

C#e56c8efa9c90d930165aee622b57e424.png

SQL Server2019

数据库信息:

服务器:.

登录用户:sa

密码:123

数据库:Architecture_demo

表名:Student77703bd4e850f50e635bbd2ee2915791.png

清楚了框架那么就开始编写C#部分的程序。


C#程序编写

编写程序用的是Visual Studio 2019.

创建项目


BLL、DAL、Model为".dll类库"项目,UI为"Windows窗体应用程序"项目。

3d466b15fd924c13ce29193600a09ff5.png

Model实体模型搭建

在Model项目里创建Students类,且Students要为public,

C#中的Students类与数据库中的Student的表,是多了一个“s”的,用于区分,

这里的属性要与数据库中的Student表要一样。

f4a635297b5828b50c6cb188e33e5231.png

usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
namespaceModel{
publicclassStudents    {
publicintstudent_ID { get; set; }
publicstringname { get; set; }
publicintage { get; set; }
publicstringgender { get; set; }
    }
}

DAL数据访问层

首先在UI项目里的App.config文件中添加一段代码,在数据库服务器名称和密码发生改变时,不用修改程序代码,只需要修改App.config文件中这段代码既可

Server:数据库服务器的名称   DataBase:数据库名称

Uid:用户名  Pwd:密码

<connectionStrings><addname="connString"connectionString="Server=DESKTOP-D258CHD\WINCC;DataBase=Architecture_demo;Uid=sa;Pwd=123"/></connectionStrings>

070cf02c509f562cd9e223f39a7cc216.png

然后返回到DAL项目,在DAL项目引用里添加System.Configuration,用于读取UI项目的App.config文件。c6f621e507b2ceaab78ce639c161da1d.png


接下来在DAL项目里创建SQLHelper类,SQLHelper要为public,同时引入System.Data、System.Data.SqlClient、System.Configuration


System.Data:提供对数据的操作


System.Data.SqlClient:提供对数据库的操作


System.Configuration:提供对App.config的操作


以下是代码:

usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
usingSystem.Data;
usingSystem.Data.SqlClient;
usingSystem.Configuration;
namespaceDAL{
publicclassSQLHelper    {
privatestaticreadonlystringconnString=ConfigurationManager.ConnectionStrings["connString"].ToString();
/// <summary>/// 对数据库进行增删改/// </summary>/// <param name="sql">要查询的SQL语句</param>/// <returns>返回受影响的行数</returns>publicstaticintUpdate(stringsql)
        {
//与数据库连接的字符串SqlConnectionconn=newSqlConnection(connString);
//SQL语句SqlCommandcmd=newSqlCommand(sql, conn);
try            {
//与数据库建立连接conn.Open();
returncmd.ExecuteNonQuery();
            }
catch (Exceptionex)
            {
throwex;
            }
finally            {
//断开与数据库的连接conn.Close();
            }
        }
/// <summary>/// 执行单一结果查询/// </summary>/// <param name="sql">要查询的SQL语句</param>/// <returns>返回单一的查询结果</returns>publicstaticobjectGetSingleResult(stringsql)
        {
SqlConnectionconn=newSqlConnection(connString);
SqlCommandcmd=newSqlCommand(sql, conn);
try            {
conn.Open();
returncmd.ExecuteScalar();
            }
catch (Exceptionex)
            {
throwex;
            }
finally            {
conn.Close();
            }
        }
/// <summary>/// 执行一个结果集的查询/// </summary>/// <param name="sql">要查询的SQL语句</param>/// <returns>返回一个SqlDataReader对象</returns>publicstaticSqlDataReaderGetReader(stringsql)
        {
SqlConnectionconn=newSqlConnection(connString);
SqlCommandcmd=newSqlCommand(sql, conn);
try            {
conn.Open();
SqlDataReaderobjReader=cmd.ExecuteReader(CommandBehavior.CloseConnection);
returnobjReader;
            }
catch (Exceptionex)
            {
throwex;
            }
        }
    }
}

BLL业务逻辑层

在BLL里创建StudentService类,StudentService要为public

引入DAL、Model

eaa76bc43bf31d411d02335be478c3c0.png

接着在StudentService类的代码里引入

System.Data、System.Data.SqlClient


以下是代码:

usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
usingSystem.Data;
usingSystem.Data.SqlClient;
usingDAL;
usingModel;
namespaceBLL{
publicclassStudentService    {
/// <summary>/// 增加一条数据/// </summary>/// <param name="objStudent"></param>/// <returns></returns>publicintAddStudent(StudentsobjStudent)
        {
//【1】编写sql语句StringBuildersqlBuilder=newStringBuilder("insert into Student ");
sqlBuilder.Append(" (name,age,gender) ");
sqlBuilder.Append(" values('{0}',{1},'{2}');select @@identity ");
//【2】解析对象stringsql=string.Format(sqlBuilder.ToString(), objStudent.name,objStudent.age,objStudent.gender);
//【3】提交SQL语句try            {
returnConvert.ToInt32(SQLHelper.GetSingleResult(sql));//执行sql语句,返回学号            }
catch (Exceptionex)
            {
thrownewException("添加学员时数据访问异常:"+ex.Message);
            }
        }
/// <summary>/// 删除一条数据/// </summary>/// <param name="studentId"></param>/// <returns></returns>publicintDeleteStudent(stringstudentId)
        {
stringsql="delete from Student where Student_ID="+studentId;
try            {
returnSQLHelper.Update(sql);
            }
catch (SqlExceptionex)
            {
//547是数据库返回的消息,返回改该消息表示不能被删除if (ex.Number==547)
                {
thrownewException("该学号被其他实体引用,不能直接删除该学员对象!");
                }
else                {
thrownewException("删除学员对象发生数据异常!"+ex.Message);
                }
            }
catch (Exceptionex)
            {
throwex;
            }
        }
/// <summary>/// 修改学生信息/// </summary>/// <param name="objStudent"></param>/// <returns></returns>publicintModifyStudent(StudentsobjStudent)
        {
StringBuildersqlBuilder=newStringBuilder();
sqlBuilder.Append("update Student set name='{0}',age={1},gender='{2}'  ");
stringsql=string.Format(sqlBuilder.ToString(), objStudent.name,objStudent.age,objStudent.gender);
try            {
returnSQLHelper.Update(sql);
            }
catch (Exceptionex)
            {
thrownewException("修改学员信息是数据访问发生异常:"+ex.Message);
            }
        }
/// <summary>/// 根据学号查询学生/// </summary>/// <param name="studentId"></param>/// <returns></returns>publicStudentsGetStudentById(stringstudentId)
        {
stringsql="select Student_ID,name,age,gender from Student ";
sql+=" where Student_ID="+studentId;
SqlDataReaderobjReader=SQLHelper.GetReader(sql);
StudentsobjStudent=null;
if (objReader.Read())
            {
objStudent=newStudents()
                {
student_ID=Convert.ToInt32(objReader["student_ID"]),
name=objReader["name"].ToString(),
age=Convert.ToInt32(objReader["age"]),
gender=objReader["gender"].ToString()
                };
            }
objReader.Close();
returnobjStudent;
        }
    }
}

UI表现层

在工具箱找到TabControl,拖动到窗口

7795f4ca6f817025ed0a2a489eb66b52.png

增加两个页面,第一个为“增”,第二个为“删、改、查”

“增”界面

这里说明一下因为学号在数据库里面是主键,是不能更改的,但是在添加其他数据的时候,学号是会自增数据的,每一条数据+1,这个每次增加的数可以在数据库里面修改的

e4155bab1a864dae91b7f92ae185182a.png

“删、改、查”界面

ff349150c6bb61810e8faeefb96d0aa8.png

 
         

UI代码

首先在UI项目里引入DAL、BLL、Model5f439f73bef2c9864330aceb14d4dc35.png

“增”界面代码

usingSystem;
usingSystem.Collections.Generic;
usingSystem.ComponentModel;
usingSystem.Data;
usingSystem.Drawing;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
usingSystem.Windows.Forms;
usingDAL;
usingBLL;
usingModel;
namespaceUI{
publicpartialclassForm1 : Form    {
privateStudentServiceobjStudentService=newStudentService();
List<Students>stuList=newList<Students>();//用来临时保存学员对象publicForm1()
        {
InitializeComponent();
        }
/// <summary>/// 添加按钮/// </summary>/// <param name="sender"></param>/// <param name="e"></param>privatevoidbtn_Add_Click(objectsender, EventArgse)
        {
//封装学生对象StudentsojbStudent=newStudents()
            {
name=this.txt_Z_name.Text.Trim(),
age=Convert.ToInt32(this.txt_Z_age.Text.Trim()),
gender=this.rdoMale.Checked?"男" : "女"            };
//调用后台数据访问方法intstudentId=objStudentService.AddStudent(ojbStudent);
try            {
//同步显示添加的学员ojbStudent.student_ID=studentId;
this.stuList.Add(ojbStudent);
this.dgvStudentList.DataSource=null;
this.dgvStudentList.DataSource=this.stuList;
//询问是否继续添加DialogResultresult=MessageBox.Show("新学员添加成功!是否继续添加?", "提示信息", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (result==DialogResult.Yes)
                {
//清空用户输入的信息foreach (Controliteminthis.gbstuinfo.Controls)
                    {
if (itemisTextBox)
                        {
item.Text="";
                        }
elseif (itemisRadioButton)
                        {
                            ((RadioButton)item).Checked=false;
                        }
                    }
                }
            }
catch (Exceptionex)
            {
MessageBox.Show("添加学员出现数据访问异常"+ex.Message);
            }
        }
    }
}

25182aa720d9facbe9b6543f8716f779.png

UI全部代码

usingSystem;
usingSystem.Collections.Generic;
usingSystem.ComponentModel;
usingSystem.Data;
usingSystem.Drawing;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
usingSystem.Windows.Forms;
usingDAL;
usingBLL;
usingModel;
namespaceUI{
publicpartialclassForm1 : Form    {
privateStudentServiceobjStudentService=newStudentService();
List<Students>stuList=newList<Students>();//用来临时保存学员对象publicForm1()
        {
InitializeComponent();
        }
/// <summary>/// 添加按钮/// </summary>/// <param name="sender"></param>/// <param name="e"></param>privatevoidbtn_Add_Click(objectsender, EventArgse)
        {
//封装学生对象StudentsojbStudent=newStudents()
            {
name=this.txt_Z_name.Text.Trim(),
age=Convert.ToInt32(this.txt_Z_age.Text.Trim()),
gender=this.rdoMale.Checked?"男" : "女"            };
//调用后台数据访问方法intstudentId=objStudentService.AddStudent(ojbStudent);
try            {
//同步显示添加的学员ojbStudent.student_ID=studentId;
this.stuList.Add(ojbStudent);
this.dgvStudentList.DataSource=null;
this.dgvStudentList.DataSource=this.stuList;
//询问是否继续添加DialogResultresult=MessageBox.Show("新学员添加成功!是否继续添加?", "提示信息", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (result==DialogResult.Yes)
                {
//清空用户输入的信息//gbstuinfo是“增”界面的“基本信息”框,也就是工具箱的GroupBox控件foreach (Controliteminthis.gbstuinfo.Controls)
                    {
if (itemisTextBox)
                        {
item.Text="";
                        }
elseif (itemisRadioButton)
                        {
                            ((RadioButton)item).Checked=false;
                        }
                    }
                }
            }
catch (Exceptionex)
            {
MessageBox.Show("添加学员出现数据访问异常"+ex.Message);
            }
        }
/// <summary>/// 查询按钮/// </summary>/// <param name="sender"></param>/// <param name="e"></param>privatevoidbtn_Inquire_Click(objectsender, EventArgse)
        {
if (this.txt_S_StudentId.Text.Length==0)
            {
MessageBox.Show("请输入学号!", "查询提示!");
return;
            }
StudentsobjStudent=objStudentService.GetStudentById(this.txt_S_StudentId.Text.Trim());
this.stuList.Add(objStudent);
this.dgvStudentList2.DataSource=null;
this.dgvStudentList2.DataSource=this.stuList;
        }
/// <summary>/// 修改按钮/// </summary>/// <param name="sender"></param>/// <param name="e"></param>privatevoidbtn_Edit_Click(objectsender, EventArgse)
        {
if (txt_S_Id.Text==""||txt_S_name.Text==""||txt_S_age.Text==""||rdo_S_Male.Checked==false&&rdo_S_Female.Checked==false)
            {
MessageBox.Show("数据不完整", "提示!");
return;
            }
//封装学员对象StudentsobjStudent=newStudents()
            {
student_ID=Convert.ToInt32(this.txt_S_Id.Text.Trim()),
name=this.txt_S_name.Text.Trim(),
age=Convert.ToInt32(this.txt_S_age.Text.Trim()),
gender=this.rdoMale.Checked?"男" : "女"            };
try            {
if (objStudentService.ModifyStudent(objStudent) ==1)
                {
MessageBox.Show("学员信息修改成功!", "提示信息");
                }
            }
catch (Exceptionex)
            {
MessageBox.Show(ex.Message, "提示信息");
            }
        }
privatevoiddgvStudentList2_CellClick(objectsender, DataGridViewCellEventArgse)
        {
txt_S_Id.Text=this.dgvStudentList2.CurrentRow.Cells["Student_ID"].Value.ToString();
txt_S_name.Text=this.dgvStudentList2.CurrentRow.Cells["name"].Value.ToString();
txt_S_age.Text=this.dgvStudentList2.CurrentRow.Cells["age"].Value.ToString();
if (this.dgvStudentList2.CurrentRow.Cells["gender"].Value.ToString() =="男")
            {
rdo_S_Male.Checked=true;
            }
else            {
rdo_S_Female.Checked=true;
            }
        }
//删除privatevoidbtn_Delete_Click(objectsender, EventArgse)
        {
if (this.dgvStudentList2.RowCount==0)
            {
MessageBox.Show("没有任何需要删除的学员!", "提示信息");
return;
            }
if (this.dgvStudentList2.CurrentRow==null)
            {
MessageBox.Show("请先选中要删除的学员!", "提示信息");
return;
            }
//删除前的确认DialogResultresult=MessageBox.Show("确认删除吗!", "提示信息", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
if (result==DialogResult.Cancel) return;
//获取学号stringstudentId=this.dgvStudentList2.CurrentRow.Cells["Student_ID"].Value.ToString();
try            {
objStudentService.DeleteStudent(studentId);
dgvStudentList2.DataSource=null;
            }
catch (Exceptionex)
            {
MessageBox.Show(ex.Message, "提示信息");
            }
        }
    }
}

3c9c5dd80ba206be7841cacd465355d2.png


提示:表格的名字和数据名要与数据库的字段对应

d2f23e0862dc97c05010b8a4b06c57cc.png

演示视频

B站:https://www.bilibili.com/video/BV1Mr4y1X74a/

相关文章
|
12月前
|
存储 SQL 数据库连接
C#程序调用Sql Server存储过程异常处理:调用存储过程后不返回、不抛异常的解决方案
本文分析了C#程序操作Sql Server数据库时偶发的不返回、不抛异常问题,并提出了解决思路。首先解析了一个执行存储过程的函数`ExecuteProcedure`,其功能是调用存储过程并返回影响行数。针对代码执行被阻塞但无异常的情况,文章总结了可能原因,如死锁、无限循环或网络问题等。随后提供了多种解决方案:1) 增加日志定位问题;2) 使用异步操作提升响应性;3) 设置超时机制避免阻塞;4) 利用线程池分离主线程;5) 通过信号量同步线程;6) 监控数据库连接状态确保可用性。这些方法可有效应对数据库操作中的潜在问题,保障程序稳定性。
817 11
|
SQL 存储 关系型数据库
MySQL/SqlServer跨服务器增删改查(CRUD)的一种方法
通过上述方法,MySQL和SQL Server均能够实现跨服务器的增删改查操作。MySQL通过联邦存储引擎提供了直接的跨服务器表访问,而SQL Server通过链接服务器和分布式查询实现了灵活的跨服务器数据操作。这些技术为分布式数据库管理提供了强大的支持,能够满足复杂的数据操作需求。
639 12
|
关系型数据库 MySQL 网络安全
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
|
SQL 存储 监控
SQL Server的并行实施如何优化?
【7月更文挑战第23天】SQL Server的并行实施如何优化?
835 13
解锁 SQL Server 2022的时间序列数据功能
【7月更文挑战第14天】要解锁SQL Server 2022的时间序列数据功能,可使用`generate_series`函数生成整数序列,例如:`SELECT value FROM generate_series(1, 10)。此外,`date_bucket`函数能按指定间隔(如周)对日期时间值分组,这些工具结合窗口函数和其他时间日期函数,能高效处理和分析时间序列数据。更多信息请参考官方文档和技术资料。
565 9
|
SQL 存储 网络安全
关系数据库SQLserver 安装 SQL Server
【7月更文挑战第26天】
361 6
|
关系型数据库 MySQL 大数据
C#使用SqlSugar操作MySQL数据库实现简单的增删改查
C#使用SqlSugar操作MySQL数据库实现简单的增删改查
1050 2
|
存储 SQL C++
对比 SQL Server中的VARCHAR(max) 与VARCHAR(n) 数据类型
【7月更文挑战7天】SQL Server 中的 VARCHAR(max) vs VARCHAR(n): - VARCHAR(n) 存储最多 n 个字符(1-8000),适合短文本。 - VARCHAR(max) 可存储约 21 亿个字符,适合大量文本。 - VARCHAR(n) 在处理小数据时性能更好,空间固定。 - VARCHAR(max) 对于大文本更合适,但可能影响性能。 - 选择取决于数据长度预期和业务需求。
1402 1
|
SQL 网络协议 数据库连接
已解决:连接SqlServer出现 provider: Shared Memory Provider, error: 0 - 管道的另一端上无任何进程【C#连接SqlServer踩坑记录】
本文介绍了解决连接SqlServer时出现“provider: Shared Memory Provider, error: 0 - 管道的另一端上无任何进程”错误的步骤,包括更改服务器验证模式、修改sa用户设置、启用TCP/IP协议,以及检查数据库连接语句中的实例名是否正确。此外,还解释了实例名mssqlserver和sqlserver之间的区别,包括它们在默认设置、功能和用途上的差异。
|
SQL 安全 Java
驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接。错误:“The server selected protocol version TLS10 is not accepted by client
驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接。错误:“The server selected protocol version TLS10 is not accepted by client
1865 0