【C#】C# Winform 三层架构
一、介绍
三层架构是 C# 桌面开发中比较常用的框架,是由 表示层(UI)、业务逻辑层(BLL)和数据访问层(DAL)三层架构组成,目的是为了 “高内聚,低耦合”。开发人员分工更明确,将精力更专注于应用系统核心业务逻辑的分析、设计和开发,加快项目的进度,提高了开发效率,有利于项目的更新和维护工作。
从三层架构可以看到,很类似于 Web 前端开发的 MVC 框架(视图View,模型Model,控制Contorller),但本质上也有不同的地方,比如都有视图(三层中叫 UI),Model ,三层中没有 Contorller,但 BLL 层和 Contorller 很类似。
一个项目如果用到了三层架构,这就必然要涉及到数据库,否则就没有必要用三层架构了,下面用一张图来表示,我百度看了很多的帖子,三层架构写的基本是有一些差异的,如果你看的资料和我写的不一样,那都是正常的。
另外,各种项目根据自己的需求来,并不是所有的PC软件都要求用三层架构,用程序集划分了代码的逻辑,才是三层架构真正的意义所在。现在网上已经有很多三层架构自动生成生成软件,可以根据 sqlserver 数据库一键生成,但基本都是2016年之前的软件了,后面也没再更新了,有需要的话可以去试试。
二、搭建三层架构
新建一个基于.net6 的 winform 项目,就以登陆功能作为演示,界面如下
1.Model
添加一个 .net6 类库,取名 Model(存储数据库字段),在里面添加一个类 UserInfo
代码:
namespace Model { public class UserInfo { public string? UserName { get; set; } public string? Password { get; set; } } }
一般你数据库用户表的所有字段都要写出来,主要是方便后面将查询的数据以类对象的方式返回回来。
2.DAL
添加一个 .net6 类库,取名 DAL(数据访问层),在里面添加一个类 SqlServerHelper,这里看你用的什么数据库,如果是 mysql 就用 mysql 的查询方式,c# 查询 mysql 和 sqlserver 数据库我都有写相关的教程,有需要的可以去看看
C# 连接 SqlServer 数据库_熊思宇的博客-CSDN博客_c连接sqlserver数据库
C# 连接 MySQL 数据库_熊思宇的博客-CSDN博客_c# mysql
SqlServerHelper.cs
using System.Data; using System.Data.SqlClient; namespace SqlServer { internal class SqlServerHelper { /// <summary> /// 连接字符串 /// </summary> private string strconn = string.Empty; public SqlServerHelper(string conn) { //读取配置文件 //strconn = ConfigurationManager.AppSettings["Conn"].ToString(); //strconn = ConfigurationManager.ConnectionStrings["ConnectionString"].ToString(); strconn = conn; } /// <summary> /// 执行增删改SQL语句 /// </summary> /// <param name="cmdText">SQL语句</param> /// <returns></returns> public int ExecuteNonQuery(string cmdText) { using (SqlConnection conn = new SqlConnection(strconn)) { conn.Open(); return ExecuteNonQuery(conn, cmdText); } } /// <summary> /// 执行增删改SQL语句 /// </summary> /// <param name="conn">SqlConnection</param> /// <param name="cmdText">SQL语句<</param> /// <returns></returns> public int ExecuteNonQuery(SqlConnection conn, string cmdText) { int res; using (SqlCommand cmd = new SqlCommand(cmdText, conn)) { cmd.CommandType = CommandType.Text; res = cmd.ExecuteNonQuery(); if (conn.State == ConnectionState.Open) { conn.Close(); conn.Dispose(); } } return res; } /// <summary> /// 执行查询SQL语句 /// </summary> /// <param name="cmdText">SQL语句</param> /// <returns></returns> public DataTable ExecuteDataTable(string cmdText) { using (SqlConnection conn = new SqlConnection(strconn)) { conn.Open(); return ExecuteDataTable(conn, cmdText); } } /// <summary> /// 执行查询SQL语句 /// </summary> /// <param name="conn">SqlConnection</param> /// <param name="cmdText">SQL语句</param> /// <returns></returns> private DataTable ExecuteDataTable(SqlConnection conn, string cmdText) { DataTable dt = new DataTable(); using (SqlCommand cmd = new SqlCommand(cmdText, conn)) { cmd.CommandType = CommandType.Text; using (SqlDataAdapter sda = new SqlDataAdapter(cmd)) { sda.Fill(dt); if (conn.State == ConnectionState.Open) { conn.Close(); conn.Dispose(); } } } return dt; } /// <summary> /// 执行查询SQL语句 /// </summary> /// <param name="cmdText">SQL语句</param> /// <returns></returns> public DataTable ExecuteQuery(string cmdText) { using (SqlConnection conn = new SqlConnection(strconn)) { conn.Open(); return ExecuteQuery(conn, cmdText); } } /// <summary> /// 执行查询SQL语句 /// </summary> /// <param name="conn">SqlConnection</param> /// <param name="cmdText">SQL语句</param> /// <returns></returns> public DataTable ExecuteQuery(SqlConnection conn, string cmdText) { DataTable dt = new DataTable(); using (SqlCommand cmd = new SqlCommand(cmdText, conn)) { using (SqlDataReader sdr = cmd.ExecuteReader()) { dt.Load(sdr); sdr.Close(); sdr.Dispose(); if (conn.State == ConnectionState.Open) { conn.Close(); conn.Dispose(); } } } return dt; } } }
如果确少对应的插件,可以自己装一个
新建一个类 UserHandle,用来查询数据库并返回数据
using System.Data; namespace DAL { public class UserHandle { private const string Conn = "server=.;dataBase=Test;uid=sa;pwd=123456"; private static SqlServerHelper SqlServerHelpers = new SqlServerHelper(Conn); /// <summary> /// 用户登录 /// </summary> /// <param name="name"></param> /// <param name="pwd"></param> /// <returns></returns> public static DataTable UserLogin(string name ,string pwd) { // SQL 语句根据个人情况来写 string sql = "SELECT * FROM **********"; return SqlServerHelpers.ExecuteDataTable(sql); } /// <summary> /// 获取用户的所有数据 /// </summary> /// <param name="name"></param> /// <returns></returns> public static DataTable GetUserData(string name) { // SQL 语句根据个人情况来写 string sql = "SELECT * FROM *************"; return SqlServerHelpers.ExecuteDataTable(sql); } } }
3.BLL
添加一个 .net6 类库,取名 BLL(业务逻辑层),由于后面的代码需要获取到数据库数据,所以要添加 DAL 和 Model 程序集 的引用
添加一个类 LoginHandle
using DAL; using Model; using System.Data; namespace BLL { public class LoginHandle { /// <summary> /// 用户登录 /// </summary> /// <param name="username">用户名</param> /// <param name="password">密码</param> /// <returns>是否能够登录</returns> public static bool UserLogin(string username, string password) { DataTable dataTable = UserHandle.UserLogin(username, password); if (dataTable == null || dataTable.Rows.Count == 0) { Console.WriteLine("查询的数据为空"); return false; } string? user = dataTable.Rows[0][0].ToString(); string? pwd = dataTable.Rows[0][1].ToString(); if (username.Equals(user) && password.Equals(pwd)) { return true; } return false; } /// <summary> /// 获取用户的所有数据 /// </summary> /// <param name="username"></param> /// <returns></returns> public static UserInfo? GetUserData(string username) { DataTable dataTable = UserHandle.GetUserData(username); if (dataTable == null || dataTable.Rows.Count == 0) { Console.WriteLine("查询的数据为空"); return null; } UserInfo userInfo = new UserInfo(); userInfo .UserName = dataTable.Rows[0][0].ToString(); userInfo .Password = dataTable.Rows[0][1].ToString(); return userInfo; } } }
4.UI
UI层就是创建项目时的 winform 项目,上面的工作完成后,配置大概就如下界面
接下来就添加项目引用了,将 BLL和 Model 层添加进来
给界面的登录按钮,添加点击事件
using BLL; using Model; namespace 三层架构Demo { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Button_Login_Click(object sender, EventArgs e) { string username = TextBox_UserName.Text; string password = TextBox_Password.Text; if(string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password)) { Console.WriteLine("输入框不能为空"); return; } //第一种方式 bool result = LoginHandle.UserLogin(username, password); if(result) { Console.WriteLine("登录成功!"); //跳转界面 //.... } else { Console.WriteLine("登录失败"); } //第二种方式 UserInfo? userInfo = LoginHandle.GetUserData(username); if(userInfo != null) { if(userInfo.Password != password) { Console.WriteLine("密码不正确"); return; } Console.WriteLine("登录成功!"); } } } }
源码:点击下载
结束
如果这个帖子对你有所帮助,欢迎 关注 、点赞 、留言
end
猜你喜欢
- 【C#】Winform NanUI 0.77版本 读取嵌入式资源
- 引入NanUI框架这三个组件都要引入了,NetDimension.NanUI.AssemblyResourceHandler 是属于嵌入式资源部分,下载地址:由于作者已经废弃了这个版本,在VS2019中的 NuGet 程序包 中已经下载不了,我这里上传了,有需要的可以点击下面链接下载NanUI.AssemblyResourceHandler.0.7.4 下载 另外,NanUI.AssemblyResourceHandler 源码github地址:GitHub - maxjov
- 【C#】C# Winform 文本面板带滚动条
- 在PC软件开发中经常有这样的需求,需要在一个固定大小的面板中显示一些内容,并且面板能上下拖动,将所有的内容完整的展示,有点类似网页上看新闻,如果要在 winfrom 中要如何实现的呢,下面就演示如何实现的吧效果:1.新建一个winform 项目,在界面中拖入一个Panel 将 panel1 的 AutoScroll 设置为 True2.再次拖入一个 Panel ,将高度拉长,这时就自动出现了滚动条,只是此时里面还没有任何内容,下面就在 panel2 中加入一点内容。
- 【C#】C# Winform 自定义进度条ProgressBar
- 效果:一、前言Winfrom各种老毛病真的不适合做大型项目,甚至中型项目都不适合,一些小功能都能把你折腾半死,比如,我想在界面上显示一个进度条,用来显示现在硬盘和内存已经使用了多少,使用了 ProgressBar 控件你看看效果:进度条中间一直有个白色光影在晃来晃去的,是不是想让别人感慨:“哇!好强的光芒,我的眼睛快睁不开了...”。而且背景颜色无法改变,这个动画也无法关掉,为了解决这两个问题,我找了很久,终于找到了下面的解决方法。二、自定义进度条于是我在网上找了一些资料,有到效果有,但不是特别
- 【C#】从零开始用C#写一个桌面应用程序(二)一个表白程序
- 恶搞表白小程序如何添加按钮,如何添加属性和事件请移步前文。基础操作第一步:新建窗口 在工具箱内找到label和button,拖到form上,设置它们的size属性,autosize属性,text属性。第二步:添加事件为了实现我们的效果,需要给三个按钮分别设计点击事件,鼠标移入事件,鼠标点下事件。分别为click,mouseenter,mousedown事件。第三步:实现移动逻辑this获取form对象,clientsize获取实时大小,使用随机数值,设置对应按钮位置。将对应
- 【C#】C# Winfrom 右键菜单
- 目录一、概述二、新建 winform 项目三、给图片控件添加右键菜单四、给菜单添加点击事件五、测试结束一、概述ContextMenuStrip 是 Windows 窗体应用程序中的一个控件,它提供了一个弹出菜单,用于在用户右键单击控件或其他界面元素时显示上下文相关的选项。它通常用于在图形用户界面中提供快捷操作和功能。ContextMenuStrip 控件可以通过在 Visual Studio 的设计器中拖放方式添加到窗体上,或者通过编程方式创建和配置。它可以与其他控件(如按钮、文本框等
- 【C#】C# Winform 配置文件App.config
- 目录一、简介二、添加引用 三、添加节点1.普通配置节点2.数据源配置节点四、管理类 ConfigHelper.cs1.获取配置节点2.更新或加入配置节点结束一、简介在C#中,配置文件很常用,ASP.NET 和 Winform 名称不同,用法一样,如下图config 文件通常用来存储一些需要修改的数据,比如用户名密码,连接数据库的IP地址等,而不是在代码中写死。有人可能会问,那我自己自定义一个配置文件也行,为什么要用它这个?区别当然有,微软自己封装的读取和写入会更简单一些,你自己封装的,
- 【C#】C#超急速举例入门-适用有C/C++语言基础
- 前提编程环境:vs2022电脑系统:win10学习目的:能看懂c#,不纠结各种细节,快速适应开发。入门篇程序结构变量类型类似c语言,不掌握细节,int,float,double都有。输入输出Console.WriteLine("变量0:{0}", para0); var a=Console.ReadLine(); 运算符几乎相同。sizeof();typeof();取地址,取值:&,*;三元运算符: ? :判断类型:is强制转换:as。注
- 【C#】c#开发桌面应用程序用什么框架
- style="text-wrap: wrap;">在C#开发桌面应用程序时,可以使用以下几种常见的框架:</p><ol class=" list-paddingleft-2" style="width: 1529.1px; text-wrap: wrap;"><li><p>Windows Forms:这是一种由.NET Framework提供的GUI框架,它提供了丰富的GUI控件和易于使用的编程模型。Windows Forms在C#开发领域中使用非常广泛,并且已经存在多年,获得了广泛的支持和优化。</p></li></ol