您的当前位置:首页>全部文章>文章详情

【C#】C# Winform 三层架构

CrazyPanda发表于:2024-02-03 22:27:10浏览:294次TAG:


一、介绍

三层架构是 C# 桌面开发中比较常用的框架,是由 表示层(UI)、业务逻辑层(BLL)和数据访问层(DAL)三层架构组成,目的是为了 “高内聚,低耦合”。开发人员分工更明确,将精力更专注于应用系统核心业务逻辑的分析、设计和开发,加快项目的进度,提高了开发效率,有利于项目的更新和维护工作。

从三层架构可以看到,很类似于 Web 前端开发的 MVC 框架(视图View,模型Model,控制Contorller),但本质上也有不同的地方,比如都有视图(三层中叫 UI),Model ,三层中没有 Contorller,但 BLL 层和 Contorller 很类似。

一个项目如果用到了三层架构,这就必然要涉及到数据库,否则就没有必要用三层架构了,下面用一张图来表示,我百度看了很多的帖子,三层架构写的基本是有一些差异的,如果你看的资料和我写的不一样,那都是正常的。

1.png

另外,各种项目根据自己的需求来,并不是所有的PC软件都要求用三层架构,用程序集划分了代码的逻辑,才是三层架构真正的意义所在。现在网上已经有很多三层架构自动生成生成软件,可以根据 sqlserver 数据库一键生成,但基本都是2016年之前的软件了,后面也没再更新了,有需要的话可以去试试。


二、搭建三层架构

新建一个基于.net6 的 winform 项目,就以登陆功能作为演示,界面如下

1.png


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;
        }
 
    }
}

如果确少对应的插件,可以自己装一个

1.png


新建一个类 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 程序集 的引用

1.png

 添加一个类 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 项目,上面的工作完成后,配置大概就如下界面

1.png

接下来就添加项目引用了,将 BLL和 Model 层添加进来

1.png

给界面的登录按钮,添加点击事件

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 三层架构_c# 界面开发框架-CSDN博客

猜你喜欢

【C#】C# Winform 配置文件App.config
目录一、简介二、添加引用&nbsp;三、添加节点1.普通配置节点2.数据源配置节点四、管理类 ConfigHelper.cs1.获取配置节点2.更新或加入配置节点结束一、简介在C#中,配置文件很常用,ASP.NET 和 Winform 名称不同,用法一样,如下图config 文件通常用来存储一些需要修改的数据,比如用户名密码,连接数据库的IP地址等,而不是在代码中写死。有人可能会问,那我自己自定义一个配置文件也行,为什么要用它这个?区别当然有,微软自己封装的读取和写入会更简单一些,你自己封装的,
发表于:2024-01-31 浏览:385 TAG:
【C#】C# Winform ListView用法
目录添加标题显示网格添加数据到表格中自定义其他属性结束添加标题在 Winfrom 界面中添加一个 ListView 组件,然后点击右上角的箭头,点击编辑列添加下面标题,然后点击确定此时 ListView 中还是一片空白,不能显示这些标题,在视图这里选择 Details就会如下图所示,虽然标题出来了,内容确实一块白版,此时还是觉得 DataGridView 组件好用啊显示网格此时,表格只是一片空白,可以在属性面板中设置,显示网格,如下图&nbsp;&nbsp;这时,就如下图所示,效果就出来了,但是
发表于:2024-01-31 浏览:379 TAG:
【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
发表于:2024-01-27 浏览:452 TAG:
【C#】C# Winform 文本面板带滚动条
在PC软件开发中经常有这样的需求,需要在一个固定大小的面板中显示一些内容,并且面板能上下拖动,将所有的内容完整的展示,有点类似网页上看新闻,如果要在 winfrom 中要如何实现的呢,下面就演示如何实现的吧效果:1.新建一个winform 项目,在界面中拖入一个Panel&nbsp;将 panel1 的&nbsp;AutoScroll 设置为 True2.再次拖入一个&nbsp;Panel ,将高度拉长,这时就自动出现了滚动条,只是此时里面还没有任何内容,下面就在 panel2 中加入一点内容。
发表于:2024-02-03 浏览:330 TAG:
【C#】C#的DateTimePicker控件(日期控件)
目录一、使用DateTimePicker控件显示时间二、使用DateTimePicker控件以自定义格式显示日期三、返回DateTimePicker控件中选择的日期1.源码2.生成效果&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DateTimePicker控件(日期控件)用于选择日期和时间,DateTimePicker控件只能选择一个时间,而不是连续的时间段,也可以直接输入日期和时间。一、使用DateTimePicker控件显示时间&nbsp;
发表于:2024-01-29 浏览:391 TAG:
【C#】从零开始用C#写一个桌面应用程序(二)一个表白程序
恶搞表白小程序如何添加按钮,如何添加属性和事件请移步前文。基础操作第一步:新建窗口&nbsp;&nbsp;在工具箱内找到label和button,拖到form上,设置它们的size属性,autosize属性,text属性。第二步:添加事件为了实现我们的效果,需要给三个按钮分别设计点击事件,鼠标移入事件,鼠标点下事件。分别为click,mouseenter,mousedown事件。第三步:实现移动逻辑this获取form对象,clientsize获取实时大小,使用随机数值,设置对应按钮位置。将对应
发表于:2024-01-30 浏览:304 TAG:
【C#】C# Winform SplitContainer组件创建侧边菜单
效果一,SplitContainer 基本操作新建一个 Winform 项目,在Form1中拖进一个 SplitContainer 组件默认的界面如下这时候,你会发现,左侧菜单栏的宽度也太宽了吧,按照以前的经验,你一定会用鼠标去拖拽,这时候你就会发现,鼠标根本拖不动,不信你可以试试这时候,我们按Esc键,鼠标再移动到边框的时候,鼠标图标就会变成一个 “+” 状的图标,这时候就可以拖拽了此时,左侧的Panel1内还没有任何组件,运行后的效果我们添加一个按钮到&nbsp;Panel1 试试运行后发现
发表于:2024-02-01 浏览:550 TAG:
【C#】C#实现Excel合并单元格数据导入数据集
目录功能需求Excel与DataSet的映射关系范例运行环境Excel DCOM 配置设计实现组件库引入方法设计返回值&nbsp;参数设计打开数据源并计算Sheets拆分合并的单元格创建DataTable将单元格数据写入DataTable总结功能需求将Excel里的worksheet表格导入到DataSet里,是项目应用里常用的一种操作。一般情况下,worksheet是一个标准的二维数组,如下图:我们可以效仿 MS SQL SERVER 的一些基本导入选项,如首行是否包含数据,要导入哪个Shee
发表于:2024-01-29 浏览:356 TAG:
【C#】C# Winform 热更新 基于ECSharp框架
目录一、简介二、&nbsp;ECSharp热更新演示三、Winform 热更新实战结束一、简介ECSharp (原:EasySharpFrame)github 地址:https://github.com/suxf/ECSharp介绍:1.HTTP服务 2.Websocket服务 3.HyperSocket&lt;自定义Socket服务&gt; 4.TimeFlow&lt;时间流&gt; 5.Sqlserver数据库助手 6.Mysql数据助手 7.Redis数据库助手 8.Log功能 9.热更新
发表于:2024-02-05 浏览:305 TAG:
【C#】C# NLua Winform 热更新
一、概述NLua 是一个用于 .NET 平台的 Lua 脚本绑定库。它允许在 C# 代码中嵌入 Lua 脚本,并允许两者之间进行交互。NLua 的主要特点包括:轻量级:NLua 是一个轻量级的库,易于集成到现有的 .NET 项目中。动态类型:Lua 是动态类型的语言,这意味着变量的类型可以在运行时改变。灵活的绑定:NLua 提供了灵活的绑定机制,使得 C# 和 Lua 之间的数据交互变得简单。丰富的 API:NLua 提供了丰富的 API,以便在 Lua 脚本中调用 .NET 的类和方法。调试支
发表于:2024-02-18 浏览:358 TAG: