WinFroms基于三层构造设计模式的框架所设计的代码生成器1.0

news2025/2/26 6:13:46

软件开发模式——三层架构

此文章需要在读懂 以上这篇架构模式的基础上再继续往下深入学习简化

目录

1.前言

2.框架准备

3 .coboBox的数据绑定

4.创建文件夹 

5.工具方法

6.生成一个数据库访问助手类SqlHelper 

 7.生成模型层Model

8.生成数据访问层DAL层 

9.生成业务逻辑层BLL层 

10.config配置文件的连接字符串 

11.生成按钮调用方法执行生成操作 


1.前言

在你们学习了三层架构开发模式之后,一定知道这三层中需要写 数据表的实体类对象,数据访问层的对应语句以及业务逻辑层的条件处理,对于一些简单的单个数据表来说工作量可能不算大,可是如果需要使用的项目是一种大型数据库的话处理起来的代码量就十分庞大了,由此我们可以给自己偷个懒,但是前提是这种自身的基础够扎实哦,废话不多说,下面步入正题.
 

2.框架准备

 目标框架:.NET Framework 4.7.2  (作者制作时学习的框架版本)

 输出类型:windows应用程序
界面采用一个Form主窗体 ,三个TextBox文本框,一个comboBox下拉项框和一个触发点击事件的按钮.

 文本框的初始值可以设置为你目前自己电脑的数据库的服务器名,用户名和密码
简单的设置textBox的text属性,你能看到这一步相信这种简单的步骤就不需要我详细说怎么设置了吧
 

3 .coboBox的数据绑定
 

 这个下拉框的绑定方法采用 comboBox1_DropDown当下拉列表框(ComboBox)的下拉列表部分展开时触发的事件
可能有些人会问到为什么不在load事件程序加载时直接绑定?

因为这个下拉框的值绑定需要访问到数据库,所以就用得上与数据库进行交互,有些小伙伴的文本框不一定会给到初始值所以考虑到这一点才采用DropDpwn下拉部分展示时才触发。

//全局变量
string strsql="";
//路径,后续需要用到的
string path = "";
//数据库连接
public SqlConnection conn = null;

//下拉框展开触发事件
private void comboBox1_DropDown(object sender, EventArgs e)
{
    //通过文本框采集的信息拼装成访问数据库连接字符串
    strsql = $"server={textBox1.Text};uid={textBox2.Text};pwd={textBox3.Text};database=master";
    //需要使用的查询语句 sys.databases 查询所有的数据库
    string sql = "select * from sys.databases";
    //异常处理
    try
    {
        //创建数据库连接
        conn = new SqlConnection(strsql);
        //打开数据库连接
        conn.Open();
        //对当前数据库执行一条T-SQL语句
        SqlCommand com = new SqlCommand(sql, conn);
        //返回一个读取器
        SqlDataReader red = com.ExecuteReader();
        //创建一个list集合来接收数据库名字
        List<string> list = new List<string>();
        //循环读取器将查询到的数据库名添加到list集合中
        while (red.Read())
        {
            list.Add(red["name"].ToString());
        }
        //关闭数据库连接
        conn.Close();
        //设置下拉框的显示源
        comboBox1.DataSource = list;
        //控件使用数据源对象的 name 属性作为显示文本
        comboBox1.DisplayMember = "name";
    }
    catch (Exception)
    {
        //发生异常的提示信息
        MessageBox.Show("发生错误了,请检查用户名或密码是否正确!");
    }
    
}

到这一步我们的下拉框控件的数据就会在点击下拉框展开时显示所有的数据库名称
接下来我们进入复杂的生成按钮

 

4.创建文件夹
 

 在点击生成的时候我们的数据库可能会有多张表和视图,统一的后缀为.cs,我们这个时候就需要使用一个文件夹来将生成的各个层来区分开来,不然全部散落在一堆视觉效果上就不美观
 

 //创建文件夹的方法
 //参数1:表名 参数2:写入文件的内容 参数3:文件夹名 参数4:表名层后缀
 public void CreateFile(string tableName,string msg,string dirName,string ex)
 {
     //判断拼接路径上的文件夹是否存在,不存在重新创建文件夹
     if (!Directory.Exists(path + "\\" + dirName))
     {
         Directory.CreateDirectory(path + "\\" + dirName);
     }
     //创建一个新文件 path + firname 路径 后面为拼接的文件名 最后加后缀
     StreamWriter sw=new StreamWriter(path + "\\" + dirName+"\\"+tableName+ex+".cs");
     //写入内容
     sw.Write(msg);
     sw.Close();
 }


//生成按钮的点击事件
private void button1_Click(object sender, EventArgs e)
{
    try
    {
        //下拉框选项不为空
        if (!string.IsNullOrEmpty(comboBox1.Text))
        {
            //弹窗提示用户选择文件路径
            FolderBrowserDialog fbd = new FolderBrowserDialog();
            //获取文件对话框的返回值
            DialogResult ds = fbd.ShowDialog();
            //用户选择了路径地址
            if (ds == DialogResult.OK)
            {
                //将选中的路径赋值给全局变量
                path = fbd.SelectedPath;
                //执行生成文件的方法........(先行省略)
                //弹窗提示成功
                MessageBox.Show("生成成功!");
                

            }
        }
        else { MessageBox.Show("你不选数据库该让我怎么工作?"); }
    }
    catch (Exception ex)
    {

        MessageBox.Show("发生错误:"+ex.Message);
    }
}

后续点击事件获取路径后,接下来会补全文件生成的方法

5.工具方法

在选中需要生成的数据库的时候,获取当前数据库的所有表名和视图名:

//返回一个list<string>集合
public List<string> GetTableNames()
{
    //连接字符串相比comboBox的只修改了一个当前选中的数据库
    strsql = $"server={textBox1.Text};uid={textBox2.Text};pwd={textBox3.Text};database={comboBox1.Text}";
    conn = new SqlConnection(strsql);
    conn.Open();
    //查询语句为查询数据库中的所有对象   条件:类型为表或视图
    string sql = "select * from sys.objects where type='V' or type='U'";
    SqlCommand com=new SqlCommand(sql, conn);
    SqlDataReader red = com.ExecuteReader();
    List<string> list= new List<string>();
    while (red.Read())
    {
         list.Add(red["name"].ToString());
    }
    conn.Close();
    //表名和视图名添加到list集合后return返回出
    return list;
}

这个方法会查询选中的数据库中的所有对象(再通过where条件筛选出表和视图),而后通过list集合存储所有的的视图和表名,最后再返回这个集合

 

6.生成一个数据库访问助手类SqlHelper

 

SqlHelper类用于简化在 C# 中与数据库进行交互的操作。它封装了一些常用的数据库操作方法,例如执行查询、执行非查询、执行存储过程等。 
以下提供一个常规的类源码:
 

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DAL
{
    /// <summary>
    /// 数据库辅助类
    /// </summary>
    class SqlHelper
    {
        //连接字符串
        static string conStr = System.Configuration.ConfigurationManager.ConnectionStrings["stuDB"].ToString();

        #region 增、删、改
        /// <summary>
        /// 增、删、改(普通sql语句)
        /// </summary>
        /// <param name="sql">普通sql语句</param>
        /// <returns>受影响行数</returns>
        public static int CUD(string sql)
        {
            SqlConnection conn = null;
            try
            {
                conn = new SqlConnection(conStr);
                conn.Open();
                SqlCommand com = new SqlCommand(sql, conn);
                int result = com.ExecuteNonQuery();
                return result;
            }
            catch (Exception ex)
            {
                return -1;
            }
            finally
            {
                conn.Close();
            }
        } 
        #endregion 

        #region 增、删、改(参数化的sql语句)
        /// <summary>
        /// 增、删、改(参数化的sql语句)
        /// </summary>
        /// <param name="sql">带@参数的sql语句</param>
        /// <param name="sqlParams">存储SqlParameter对象的集合</param>
        /// <returns>受影响行数</returns>
        public static int CUD(string sql, List<SqlParameter> sqlParams)
        {
            SqlConnection conn = null;
            try
            {
                conn = new SqlConnection(conStr);
                conn.Open();
                SqlCommand com = new SqlCommand(sql, conn);
                com.Parameters.AddRange(sqlParams.ToArray());//ToArray()用于将集合转换为数组
                int result = com.ExecuteNonQuery();
                return result;
            }
            catch (Exception ex)
            {
                return -1;
            }
            finally
            {
                conn.Close();
            }
        } 
        #endregion

        #region 执行查询操作,返回SqlDataReader对象
        /// <summary>
        /// 执行查询操作,返回SqlDataReader对象
        /// </summary>
        /// <param name="sql">普通sql语句</param>
        /// <returns>SqlDataReader对象</returns>
        public static SqlDataReader GetReader(string sql)
        {
            try
            {
                SqlConnection conn = new SqlConnection(conStr);
                conn.Open();
                SqlCommand com = new SqlCommand(sql, conn);
                SqlDataReader sdr = com.ExecuteReader(CommandBehavior.CloseConnection);//CommandBehavior.CloseConnection用于设置当SqlDataReader关闭时会自动关闭连接
                return sdr;
            }
            catch (Exception ex)
            {
                return null;
            }
        }
        #endregion

        #region 执行查询操作,返回SqlDataReader对象(参数化的sql语句)
        /// <summary>
        /// 执行查询操作,返回SqlDataReader对象(参数化的sql语句)
        /// </summary>
        /// <param name="sql">带@参数的sql语句</param>
        /// <param name="sqlParams">存储SqlParameter对象的集合</param>
        /// <returns>SqlDataReader对象</returns>
        public static SqlDataReader GetReader(string sql, List<SqlParameter> sqlParams)
        {
            try
            {
                SqlConnection conn = new SqlConnection(conStr);
                conn.Open();
                SqlCommand com = new SqlCommand(sql, conn);
                com.Parameters.AddRange(sqlParams.ToArray());
                SqlDataReader sdr = com.ExecuteReader(CommandBehavior.CloseConnection);//CommandBehavior.CloseConnection用于设置当SqlDataReader关闭时会自动关闭连接
                return sdr;
            }
            catch (Exception ex)
            {
                return null;
            }
        }  
        #endregion

        #region 执行查询操作,返回DataTable对象
        /// <summary>
        /// 执行查询操作,返回DataTable对象
        /// </summary>
        /// <param name="sql">普通sql语句</param>
        /// <returns>返回DataTable</returns>
        public static DataTable GetDataTable(string sql)
        {
            SqlConnection conn = null;
            try
            {
                conn = new SqlConnection(conStr);
                conn.Open();
                SqlDataAdapter sda = new SqlDataAdapter(sql, conn);
                DataTable table = new DataTable();
                sda.Fill(table);
                return table;
            }
            catch (Exception ex)
            {
                return null;
            }
            finally
            {
                conn.Close();
            }
        }
        #endregion

        #region 执行查询操作,返回DataTable对象(参数化sql语句)
        /// <summary>
        /// 执行查询操作,返回DataTable对象(参数化sql语句)
        /// </summary>
        /// <param name="sql">带@参数的sql语句</param>
        /// <param name="sqlParams">存储SqlParameter对象的集合</param>
        /// <returns>返回DataTable</returns>
        public static DataTable GetDataTable(string sql, List<SqlParameter> sqlParams)
        {
            SqlConnection conn = null;
            try
            {
                conn = new SqlConnection(conStr);
                conn.Open();
                SqlDataAdapter sda = new SqlDataAdapter();
                SqlCommand com = new SqlCommand(sql, conn);
                com.Parameters.AddRange(sqlParams.ToArray());
                sda.SelectCommand = com;
                DataTable table = new DataTable();
                sda.Fill(table);
                return table;
            }
            catch (Exception ex)
            {
                return null;
            }
            finally
            {
                conn.Close();
            }
        }  
        #endregion

        #region 执行查询语句,返回第一行第一个单元格中的数据
        /// <summary>
        /// 执行查询语句,返回第一行第一个单元格中的数据
        /// </summary>
        /// <param name="sql">普通sql语句</param>
        /// <returns>返回第一行第一个单元格中的数据</returns>
        public static object GetScalar(string sql)
        {
            SqlConnection conn = null;
            try
            {
                conn = new SqlConnection(conStr);
                conn.Open();
                SqlCommand com = new SqlCommand(sql, conn);
                object result = com.ExecuteScalar();
                return result;
            }
            catch (Exception ex)
            {
                return null;
            }
            finally
            {
                conn.Close();
            }
        }
        #endregion

        #region 执行查询语句,返回第一行第一个单元格中的数据(参数化的sql语句)
        /// <summary>
        ///  执行查询语句,返回第一行第一个单元格中的数据(参数化的sql语句)
        /// </summary>
        /// <param name="sql">带@参数的sql语句</param>
        /// <param name="sqlParams">存储SqlParameter对象的集合</param>
        /// <returns>返回第一行第一个单元格中的数据</returns>
        public static object GetScalar(string sql, List<SqlParameter> sqlParams)
        {
            SqlConnection conn = null;
            try
            {
                conn = new SqlConnection(conStr);
                conn.Open();
                SqlCommand com = new SqlCommand(sql, conn);
                com.Parameters.AddRange(sqlParams.ToArray());
                object result = com.ExecuteScalar();
                return result;
            }
            catch (Exception ex)
            {
                return null;
            }
            finally
            {
                conn.Close();
            }
        } 
        #endregion

        #region 执行存储过程返回DataTable
        /// <summary>
        /// 执行存储过程返回DataTable
        /// </summary>
        /// <param name="procName">存储过程名称</param>
        /// <param name="sqlParams">参数集合</param>
        /// <returns>DataTable</returns>
        public DataTable ProcDataTable(string procName, List<SqlParameter> sqlParams)
        {
            SqlConnection conn = null;
            try
            {
                conn = new SqlConnection(conStr);
                conn.Open();
                SqlDataAdapter sda = new SqlDataAdapter();
                SqlCommand com = new SqlCommand(procName, conn);
                com.CommandType = CommandType.StoredProcedure;
                com.Parameters.AddRange(sqlParams.ToArray());
                sda.SelectCommand = com;
                DataTable table = new DataTable();
                sda.Fill(table);
                return table;
            }
            catch (Exception ex)
            {
                return null;
            }
            finally
            {
                conn.Close();
            }
        } 
        #endregion

        #region 执行存储过程返回受影响行数
        /// <summary>
        /// 执行存储过程返回受影响行数
        /// </summary>
        /// <param name="procName">存储过程名称</param>
        /// <param name="sqlParams">参数集合</param>
        /// <returns>受影响行数</returns>
        public static int ProcCUD(string procName, List<SqlParameter> sqlParams)
        {
            SqlConnection conn = null;
            try
            {
                conn = new SqlConnection(conStr);
                conn.Open();
                SqlCommand com = new SqlCommand(procName, conn);
                com.CommandType = CommandType.StoredProcedure;
                com.Parameters.AddRange(sqlParams.ToArray());
                int result = com.ExecuteNonQuery();
                return result;
            }
            catch (Exception ex)
            {
                return -1;
            }
            finally
            {
                conn.Close();
            }
        } 
        #endregion

        #region 执行存储过程,获取输出参数的结果
        /// <summary>
        /// 执行存储过程,获取输出参数的结果
        /// </summary>
        /// <param name="procName">存储过程名称</param>
        /// <param name="sqlParams">参数集合</param>
        /// <returns></returns>
        public string ExecProc(string procName, List<SqlParameter> sqlParams)
        {
            SqlConnection conn = null;
            try
            {
                conn = new SqlConnection(conStr);
                conn.Open();
                SqlCommand com = new SqlCommand(procName, conn);
                com.CommandType = CommandType.StoredProcedure;
                com.Parameters.AddRange(sqlParams.ToArray());
                com.ExecuteNonQuery();
                string result = com.Parameters["@Ret_Msg"].Value.ToString();
                return result;
            }
            catch (Exception)
            {
                return null;
            }
            finally
            {
                conn.Close();
            }
        } 
        #endregion
    }
}

常规的操作增删改的返回值全都是受影响行数为一个int类型的返回值不同点在于sql语句不同,sql语句的编写就可以抛出到DAL层去编写
查询语句返回尽可能是一个读取器,或datatable的表数据
以上的方法也区别于普通的方法和参数化命令的方法

接下来在生成器的后台中新建一个方法用于在DAL层生成一个数据访问助手类:
 

public void CreateSqlHelper()
{
    StringBuilder sb = new StringBuilder();
    //将上面的代码段复制追加到可变字符串
    sb.Append("using System;\r\nusing System.Collections.Generic;\r\nusing System.Data;\r\nusing System.Data.SqlClient;\r\nusing System.Linq;\r\nusing System.Text;\r\nusing System.Threading.Tasks;\r\n\r\nnamespace DAL\r\n{\r\n    /// <summary>\r\n    /// 数据库辅助类\r\n    /// </summary>\r\n    class SqlHelper\r\n    {\r\n        //连接字符串\r\n        static string conStr = System.Configuration.ConfigurationManager.ConnectionStrings[\"stuDB\"].ToString();\r\n\r\n        #region 增、删、改\r\n        /// <summary>\r\n        /// 增、删、改(普通sql语句)\r\n        /// </summary>\r\n        /// <param name=\"sql\">普通sql语句</param>\r\n        /// <returns>受影响行数</returns>\r\n        public static int CUD(string sql)\r\n        {\r\n            SqlConnection conn = null;\r\n            try\r\n            {\r\n                conn = new SqlConnection(conStr);\r\n                conn.Open();\r\n                SqlCommand com = new SqlCommand(sql, conn);\r\n                int result = com.ExecuteNonQuery();\r\n                return result;\r\n            }\r\n            catch (Exception ex)\r\n            {\r\n                return -1;\r\n            }\r\n            finally\r\n            {\r\n                conn.Close();\r\n            }\r\n        } \r\n        #endregion \r\n\r\n        #region 增、删、改(参数化的sql语句)\r\n        /// <summary>\r\n        /// 增、删、改(参数化的sql语句)\r\n        /// </summary>\r\n        /// <param name=\"sql\">带@参数的sql语句</param>\r\n        /// <param name=\"sqlParams\">存储SqlParameter对象的集合</param>\r\n        /// <returns>受影响行数</returns>\r\n        public static int CUD(string sql, List<SqlParameter> sqlParams)\r\n        {\r\n            SqlConnection conn = null;\r\n            try\r\n            {\r\n                conn = new SqlConnection(conStr);\r\n                conn.Open();\r\n                SqlCommand com = new SqlCommand(sql, conn);\r\n                com.Parameters.AddRange(sqlParams.ToArray());//ToArray()用于将集合转换为数组\r\n                int result = com.ExecuteNonQuery();\r\n                return result;\r\n            }\r\n            catch (Exception ex)\r\n            {\r\n                return -1;\r\n            }\r\n            finally\r\n            {\r\n                conn.Close();\r\n            }\r\n        } \r\n        #endregion\r\n\r\n        #region 执行查询操作,返回SqlDataReader对象\r\n        /// <summary>\r\n        /// 执行查询操作,返回SqlDataReader对象\r\n        /// </summary>\r\n        /// <param name=\"sql\">普通sql语句</param>\r\n        /// <returns>SqlDataReader对象</returns>\r\n        public static SqlDataReader GetReader(string sql)\r\n        {\r\n            try\r\n            {\r\n                SqlConnection conn = new SqlConnection(conStr);\r\n                conn.Open();\r\n                SqlCommand com = new SqlCommand(sql, conn);\r\n                SqlDataReader sdr = com.ExecuteReader(CommandBehavior.CloseConnection);//CommandBehavior.CloseConnection用于设置当SqlDataReader关闭时会自动关闭连接\r\n                return sdr;\r\n            }\r\n            catch (Exception ex)\r\n            {\r\n                return null;\r\n            }\r\n        }\r\n        #endregion\r\n\r\n        #region 执行查询操作,返回SqlDataReader对象(参数化的sql语句)\r\n        /// <summary>\r\n        /// 执行查询操作,返回SqlDataReader对象(参数化的sql语句)\r\n        /// </summary>\r\n        /// <param name=\"sql\">带@参数的sql语句</param>\r\n        /// <param name=\"sqlParams\">存储SqlParameter对象的集合</param>\r\n        /// <returns>SqlDataReader对象</returns>\r\n        public static SqlDataReader GetReader(string sql, List<SqlParameter> sqlParams)\r\n        {\r\n            try\r\n            {\r\n                SqlConnection conn = new SqlConnection(conStr);\r\n                conn.Open();\r\n                SqlCommand com = new SqlCommand(sql, conn);\r\n                com.Parameters.AddRange(sqlParams.ToArray());\r\n                SqlDataReader sdr = com.ExecuteReader(CommandBehavior.CloseConnection);//CommandBehavior.CloseConnection用于设置当SqlDataReader关闭时会自动关闭连接\r\n                return sdr;\r\n            }\r\n            catch (Exception ex)\r\n            {\r\n                return null;\r\n            }\r\n        }  \r\n        #endregion\r\n\r\n        #region 执行查询操作,返回DataTable对象\r\n        /// <summary>\r\n        /// 执行查询操作,返回DataTable对象\r\n        /// </summary>\r\n        /// <param name=\"sql\">普通sql语句</param>\r\n        /// <returns>返回DataTable</returns>\r\n        public static DataTable GetDataTable(string sql)\r\n        {\r\n            SqlConnection conn = null;\r\n            try\r\n            {\r\n                conn = new SqlConnection(conStr);\r\n                conn.Open();\r\n                SqlDataAdapter sda = new SqlDataAdapter(sql, conn);\r\n                DataTable table = new DataTable();\r\n                sda.Fill(table);\r\n                return table;\r\n            }\r\n            catch (Exception ex)\r\n            {\r\n                return null;\r\n            }\r\n            finally\r\n            {\r\n                conn.Close();\r\n            }\r\n        }\r\n        #endregion\r\n\r\n        #region 执行查询操作,返回DataTable对象(参数化sql语句)\r\n        /// <summary>\r\n        /// 执行查询操作,返回DataTable对象(参数化sql语句)\r\n        /// </summary>\r\n        /// <param name=\"sql\">带@参数的sql语句</param>\r\n        /// <param name=\"sqlParams\">存储SqlParameter对象的集合</param>\r\n        /// <returns>返回DataTable</returns>\r\n        public static DataTable GetDataTable(string sql, List<SqlParameter> sqlParams)\r\n        {\r\n            SqlConnection conn = null;\r\n            try\r\n            {\r\n                conn = new SqlConnection(conStr);\r\n                conn.Open();\r\n                SqlDataAdapter sda = new SqlDataAdapter();\r\n                SqlCommand com = new SqlCommand(sql, conn);\r\n                com.Parameters.AddRange(sqlParams.ToArray());\r\n                sda.SelectCommand = com;\r\n                DataTable table = new DataTable();\r\n                sda.Fill(table);\r\n                return table;\r\n            }\r\n            catch (Exception ex)\r\n            {\r\n                return null;\r\n            }\r\n            finally\r\n            {\r\n                conn.Close();\r\n            }\r\n        }  \r\n        #endregion\r\n\r\n        #region 执行查询语句,返回第一行第一个单元格中的数据\r\n        /// <summary>\r\n        /// 执行查询语句,返回第一行第一个单元格中的数据\r\n        /// </summary>\r\n        /// <param name=\"sql\">普通sql语句</param>\r\n        /// <returns>返回第一行第一个单元格中的数据</returns>\r\n        public static object GetScalar(string sql)\r\n        {\r\n            SqlConnection conn = null;\r\n            try\r\n            {\r\n                conn = new SqlConnection(conStr);\r\n                conn.Open();\r\n                SqlCommand com = new SqlCommand(sql, conn);\r\n                object result = com.ExecuteScalar();\r\n                return result;\r\n            }\r\n            catch (Exception ex)\r\n            {\r\n                return null;\r\n            }\r\n            finally\r\n            {\r\n                conn.Close();\r\n            }\r\n        }\r\n        #endregion\r\n\r\n        #region 执行查询语句,返回第一行第一个单元格中的数据(参数化的sql语句)\r\n        /// <summary>\r\n        ///  执行查询语句,返回第一行第一个单元格中的数据(参数化的sql语句)\r\n        /// </summary>\r\n        /// <param name=\"sql\">带@参数的sql语句</param>\r\n        /// <param name=\"sqlParams\">存储SqlParameter对象的集合</param>\r\n        /// <returns>返回第一行第一个单元格中的数据</returns>\r\n        public static object GetScalar(string sql, List<SqlParameter> sqlParams)\r\n        {\r\n            SqlConnection conn = null;\r\n            try\r\n            {\r\n                conn = new SqlConnection(conStr);\r\n                conn.Open();\r\n                SqlCommand com = new SqlCommand(sql, conn);\r\n                com.Parameters.AddRange(sqlParams.ToArray());\r\n                object result = com.ExecuteScalar();\r\n                return result;\r\n            }\r\n            catch (Exception ex)\r\n            {\r\n                return null;\r\n            }\r\n            finally\r\n            {\r\n                conn.Close();\r\n            }\r\n        } \r\n        #endregion\r\n\r\n        #region 执行存储过程返回DataTable\r\n        /// <summary>\r\n        /// 执行存储过程返回DataTable\r\n        /// </summary>\r\n        /// <param name=\"procName\">存储过程名称</param>\r\n        /// <param name=\"sqlParams\">参数集合</param>\r\n        /// <returns>DataTable</returns>\r\n        public DataTable ProcDataTable(string procName, List<SqlParameter> sqlParams)\r\n        {\r\n            SqlConnection conn = null;\r\n            try\r\n            {\r\n                conn = new SqlConnection(conStr);\r\n                conn.Open();\r\n                SqlDataAdapter sda = new SqlDataAdapter();\r\n                SqlCommand com = new SqlCommand(procName, conn);\r\n                com.CommandType = CommandType.StoredProcedure;\r\n                com.Parameters.AddRange(sqlParams.ToArray());\r\n                sda.SelectCommand = com;\r\n                DataTable table = new DataTable();\r\n                sda.Fill(table);\r\n                return table;\r\n            }\r\n            catch (Exception ex)\r\n            {\r\n                return null;\r\n            }\r\n            finally\r\n            {\r\n                conn.Close();\r\n            }\r\n        } \r\n        #endregion\r\n\r\n        #region 执行存储过程返回受影响行数\r\n        /// <summary>\r\n        /// 执行存储过程返回受影响行数\r\n        /// </summary>\r\n        /// <param name=\"procName\">存储过程名称</param>\r\n        /// <param name=\"sqlParams\">参数集合</param>\r\n        /// <returns>受影响行数</returns>\r\n        public static int ProcCUD(string procName, List<SqlParameter> sqlParams)\r\n        {\r\n            SqlConnection conn = null;\r\n            try\r\n            {\r\n                conn = new SqlConnection(conStr);\r\n                conn.Open();\r\n                SqlCommand com = new SqlCommand(procName, conn);\r\n                com.CommandType = CommandType.StoredProcedure;\r\n                com.Parameters.AddRange(sqlParams.ToArray());\r\n                int result = com.ExecuteNonQuery();\r\n                return result;\r\n            }\r\n            catch (Exception ex)\r\n            {\r\n                return -1;\r\n            }\r\n            finally\r\n            {\r\n                conn.Close();\r\n            }\r\n        } \r\n        #endregion\r\n\r\n        #region 执行存储过程,获取输出参数的结果\r\n        /// <summary>\r\n        /// 执行存储过程,获取输出参数的结果\r\n        /// </summary>\r\n        /// <param name=\"procName\">存储过程名称</param>\r\n        /// <param name=\"sqlParams\">参数集合</param>\r\n        /// <returns></returns>\r\n        public string ExecProc(string procName, List<SqlParameter> sqlParams)\r\n        {\r\n            SqlConnection conn = null;\r\n            try\r\n            {\r\n                conn = new SqlConnection(conStr);\r\n                conn.Open();\r\n                SqlCommand com = new SqlCommand(procName, conn);\r\n                com.CommandType = CommandType.StoredProcedure;\r\n                com.Parameters.AddRange(sqlParams.ToArray());\r\n                com.ExecuteNonQuery();\r\n                string result = com.Parameters[\"@Ret_Msg\"].Value.ToString();\r\n                return result;\r\n            }\r\n            catch (Exception)\r\n            {\r\n                return null;\r\n            }\r\n            finally\r\n            {\r\n                conn.Close();\r\n            }\r\n        } \r\n        #endregion\r\n    }\r\n}\r\n");
    //调用方法创建文件
    CreateFile("SqlHelper", sb.ToString(), "DAL", "");
}

 

 7.生成模型层Model
 

 上一步的方法已经得到了当前数据库的所有表以及视图名称,有了现有条件之后就可以进行下一步操作了:获取所有表的列名以及数据类型        

public void CreateModel()
{
    //调用上一步的工具方法获取所有表和视图的name
    List<string> list =GetTableNames();
    //拼接数据库访问语句
    strsql = $"server={textBox1.Text};uid={textBox2.Text};pwd={textBox3.Text};database={comboBox1.Text}";
    //循环list所有表名
    foreach(string tableName in list)
    {
        //创建一个可变字符串
        StringBuilder sb = new StringBuilder();
        //追加字符串:为一个类文件的无变量基本数据格式
        sb.Append("using System;\r\nusing System.Collections.Generic;\r\nusing System.Linq;\r\nusing System.Text;\r\nusing System.Threading.Tasks;\r\n\r\nnamespace Model\r\n{\r\n    public class {tablename}:ModelBase\r\n    {\r\n        {cols}\r\n    }\r\n}");
        conn = new SqlConnection(strsql);
        conn.Open();
        //当前循环的表所有数据查询
        string sql = "select * from " + tableName;
        SqlCommand com = new SqlCommand(sql,conn);
        //设置只查询列名和主键信息 用datatable接收
        DataTable dt=com.ExecuteReader(CommandBehavior.KeyInfo).GetSchemaTable();
        //循环内新建一个可变字符串
        StringBuilder sul=new StringBuilder();
        //循环datatable的列
        for (int i = 0; i < dt.Rows.Count; i++)
        {
            //获取列名和数据类型
            string col = dt.Rows[i]["ColumnName"].ToString();
            string datatype = dt.Rows[i]["DataType"].ToString();
            拼装成公有变量字符串追加到sul字符串中
            sul.Append("public "+datatype+" "+col+"{ get; set; }"+"\n\n\t\t");
            
        }
        conn.Close();
        //替换sb字符串的指定部分
        sb.Replace("{tablename}", tableName).Replace("{cols}", sul.ToString());
        //将处理过后的文本内容写入文件夹
        CreateFile(tableName, sb.ToString(), "Model", "");

    }

    
}

CreateModel()方法会通过循环GatTableNames()方法获取的指定的数据库中所有视图以及表的名字,再通过循环查询每一个视图或表的列名和数据类型拼接成公有变量,再替换到文本格式中生成一个类文件,最后再通过CreateFile()方法写入到指定文件夹

8.生成数据访问层DAL层 
 

 有了模型层后接下来编写新建DAL层的方法,也是通过获取到对应数据库表名的方法为核心来做IO流的操作:

public void CreateDAL()
{    //获取所有视图和表
    List<string> list = GetTableNames();
    foreach (string tableName in list)
    {
        //BAL要写出的类的模板
        StringBuilder sb = new StringBuilder();
        //追加一个初步没有返回值的方法
        sb.Append("using Model;\r\nusing System;\r\nusing System.Collections.Generic;\r\nusing System.Data.SqlClient;\r\nusing System.Linq;\r\nusing System.Text;\r\nusing System.Threading.Tasks;\r\n\r\nnamespace DAL\r\n{\r\n    public class {tableName}DAL\r\n    {\r\n        public List<{tableName}> SelectAll()\r\n        {\r\n            return null;\r\n        }\r\n\r\n        public int Insert({tableName} info)\r\n        {\r\n            return 0;\r\n        }\r\n\r\n        public int DeleteForKey(object key)\r\n        {\r\n            return 0;\r\n        }\r\n\r\n        public {tableName} SelectForKey(object key)\r\n        {\r\n            return null;\r\n        }\r\n\r\n        public int Update({tableName} info)\r\n        {\r\n            return 0;\r\n        }\r\n    }\r\n}");
        //替换占位内容  修改为当前循环的表名
        sb.Replace("{tableName}", tableName);
        //调用方法创建文件 生成的文件名为表名DAL.cs
        CreateFile(tableName, sb.ToString(), "DAL", "DAL");
    }
    //创建一个SqlHelper
    CreateSqlHelper();
}

这个方法所生成的方法返回值都是空值或0,需要后续自己手动写Sql语句和返回值处理。
目前这个版本需要自己手动写DAL层的方法,后续更新可以通过反射原理来补全


 

9.生成业务逻辑层BLL层
 

最后的一个文件夹BLL业务逻辑层,原理同DAL层相似:
 

using Model;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DAL;

namespace BLL
{
    //引用对应的DAL层的方法  (BLL模板)
    public class {tableName}BLL
    {
        {tableName}DAL dal=new {tableName}DAL();
        public List<{tableName}> SelectAll()
        {
            return dal.SelectAll();
        }

        public int Insert({tableName} info)
        {
            return dal.Insert(info);
        }

        public int DeleteForKey(object key)
        {
            return dal.DeleteForKey(key);
        }

        public {tableName} SelectForKey(object key)
        {
            return dal.SelectForKey(key);
        }

        public int Update({tableName} info)
        {
            return dal.Update(info);
        }
    }
}




//创建BLL层的方法
public void CreateBLL()
{
    //直接循环GetTableNames()返回的集合
    foreach(string  tableName in GetTableNames())
    {
        创建可变字符串
        StringBuilder sb = new StringBuilder();
        //追加BLL模板
        sb.Append("using Model;\r\nusing System;\r\nusing System.Collections.Generic;\r\nusing System.Data.SqlClient;\r\nusing System.Linq;\r\nusing System.Text;\r\nusing System.Threading.Tasks;\r\nusing DAL;\r\n\r\nnamespace BLL\r\n{\r\n    public class {tableName}BLL\r\n    {\r\n        {tableName}DAL dal=new {tableName}DAL();\r\n        /// <summary>\r\n        /// 整表查询\r\n        /// </summary>\r\n        /// <returns></returns>\r\n        public List<{tableName}> SelectAll()\r\n        {\r\n            return dal.SelectAll();\r\n        }\r\n        /// <summary>\r\n        /// 通用添加方法\r\n        /// </summary>\r\n        /// <param name=\"info\">实体类</param>\r\n        /// <returns>返回受影响行数</returns>\r\n        public int Insert({tableName} info)\r\n        {\r\n            return dal.Insert(info);\r\n        }\r\n        /// <summary>\r\n        /// 主键条件删除\r\n        /// </summary>\r\n        /// <param name=\"key\">主键编号</param>\r\n        /// <returns>返回受影响行数</returns>\r\n        public int DeleteForKey(object key)\r\n        {\r\n            return dal.DeleteForKey(key);\r\n        }\r\n        /// <summary>\r\n        /// 单条数据查询\r\n        /// </summary>\r\n        /// <param name=\"key\">主键编号</param>\r\n        /// <returns>返回实体类</returns>\r\n        public {tableName} SelectForKey(object key)\r\n        {\r\n            return dal.SelectForKey(key);\r\n        }\r\n        /// <summary>\r\n        /// 条件组合查询\r\n        /// </summary>\r\n        /// <param name=\"obj\"></param>\r\n        /// <returns></returns>\r\n        public List<{tableName}> SelectWhere(object obj)\r\n        {\r\n            string sqlwhere = \"\";\r\n            return dal.SelectWhere(sqlwhere);\r\n        }\r\n        /// <summary>\r\n        /// 通用修改方法\r\n        /// </summary>\r\n        /// <param name=\"info\"></param>\r\n        /// <returns></returns>\r\n        public int Update({tableName} info)\r\n        {\r\n            return dal.Update(info);\r\n        }\r\n    }\r\n}");
        //替换占位内容
        sb.Replace("{tableName}", tableName);
        //创建文件
        CreateFile(tableName,sb.ToString(),"BLL","BLL");
    }
}

生成的BLL层只有调用DAL层数据访问方法的对应方法,可以在这层自行改动对UI层传输来的数据进行二次处理和判断

 

10.config配置文件的连接字符串 

 这一步就是将打开数据库的语句自动生成一下,也就是下面这句话:
"server={textBox1.Text};uid={textBox2.Text};pwd={textBox3.Text};database={comboBox.Text}"
这句话写在config配置文件中的代码量也是比较少的,但是作者想偷懒就单独做了一个方法生成

朋友们觉得多余可以不用看这一步
 

//创建连接字符串
public string appconfig()
{
    //新建一个可变字符串
    StringBuilder sb=new StringBuilder();
    //追加链接字符串模板
    sb.Append("<connectionStrings>\r\n\t\t<add name=\"StuDB\" connectionString=\"server={server};uid={uid};pwd={pwd};database={database}\" providerName=\"System.Data.SqlClient\"/>\r\n\t</connectionStrings>");
    //将当前的窗体中的数据替换到字符串中
    sb.Replace("{server}", textBox1.Text).Replace("{uid}", textBox2.Text).Replace("{pwd}",textBox3.Text).Replace("{database}",comboBox1.Text);
    
    return sb.ToString();
}



//重载创建文件方法  生成一个.txt文件
 public void CreateFile(string tableName, string msg, string dirName)
 {
     if (!Directory.Exists(path + "\\" + dirName))
     {
         Directory.CreateDirectory(path + "\\" + dirName);
     }
     StreamWriter sw = new StreamWriter(path + "\\" + dirName + "\\" + tableName + ".txt");
     sw.Write(msg);
     sw.Close();
 }

11.生成按钮调用方法执行生成操作 

 最后一步,各层文件的生成方法现在全部写好了,现在就到了验证的时候了,回到窗体按钮的点击事件中将几个方法调用:
 

private void button1_Click(object sender, EventArgs e)
{
    try
    {
        if (!string.IsNullOrEmpty(comboBox1.Text))
        {
            FolderBrowserDialog fbd = new FolderBrowserDialog();
            DialogResult ds = fbd.ShowDialog();
            if (ds == DialogResult.OK)
            {
                path = fbd.SelectedPath;
                //创建模型层Model
                CreateModel();
                //创建数据访问层DAL
                CreateDAL();
                //创建业务逻辑层BLL
                CreateBLL();
                //调用重载的生成txt文件的方法生成连接字符串
                CreateFile("APP",appconfig(),"");
                MessageBox.Show("生成成功!");
                

            }
        }
        else { MessageBox.Show("你不选数据库该让我怎么工作?"); }
    }
    catch (Exception ex)
    {

        MessageBox.Show("发生错误:"+ex.Message);
    }
}

到这一步我们的三层架构代码生成器1.0就已经完成了,在接下来的开发中会帮助你们节省部分时间,如果在实操中遇到问题的话可以关注作者私信解决,感兴趣的朋友们可以关注作者,后续更新2.0版本的生成器
2.0的版本会通过继承,使用泛型能使类型参数化从而变得灵活和反射的逻辑来自动拼接sql语句,简化更多代码,节省更多的开发时间,更改的条件是在1.0版本之上,有兴趣的朋友可以自己先行更改。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1058000.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

VD6283TX环境光传感器驱动开发(3)----测试闪烁频率代码

VD6283TX环境光传感器驱动开发----3.测试闪烁频率代码 概述视频教学样品申请源码下载参考代码开发板设置测试结果 概述 ST提供了6283A1_AnalogFlicker代码在X-NUCLEO-6283A1获取闪烁频率&#xff0c;同时移植到VD6283TX-SATEL。 闪烁频率提取主要用于检测光源的闪烁频率&#…

在pycharm中出现下载软件包失败的解决方法

一. 一般情况下我们会选择在设置中下载软件包,过程如下. 1. 直接点击左上角的文件, 再点击设置, 再点击项目, 在右边选择python解释器,点击号,输入要下载的软件包, 在下面的一系列的包中选择相对应的包,点击安装就可以了,有的时候我们下载的是最新的版本,如果要下载固定的版本…

数据结构与算法——19.红黑树

这篇文章我们来讲一下红黑树。 目录 1.概述 1.1红黑树的性质 2.红黑树的实现 3.总结 1.概述 首先&#xff0c;我们来大致了解一下什么是红黑树 红黑树是一种自平衡的二叉查找树&#xff0c;是一种高效的查找树。红黑树具有良好的效率&#xff0c;它可在 O(logN) 时间内完…

爬虫HTTP代理:获取多种类型数据的神器

爬虫HTTP代理是一种常用的数据采集工具&#xff0c;它可以帮助用户获取各种类型的数据。以下是爬虫HTTP代理能获取的一些常见数据&#xff1a; 网页数据 爬虫HTTP代理最常用的功能就是获取网页数据。通过代理服务器&#xff0c;用户可以获取到被封锁或限制访问的网站数据&…

pytorch之nn.Conv1d详解

自然语言处理中一个句子序列&#xff0c;一维的&#xff0c;所以使用Conv1d

Linux--socket编程

socket套接字编程 一、服务器和客户端的开发步骤&#xff1a; 1、创建套接字 2、为套接字添加信息&#xff08;ip地址和端口号&#xff09; 3、监听网络连接 4、监听到有客户端接入&#xff0c;接受连接&#xff08;如没有接入&#xff0c;会发生阻塞到&#xff09; 5、数据…

【题库】咸鱼之王答题挑战题库大全

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhang.cn] [{name: , value: 未匹配到内容},# 第一期{name: 《三国演义》中&#xff0c;「大意失街亭」的是马谩&#xff1f;, value: 对},{name: 《三国演义》中&#xff0c;「挥泪斩马谩」的是孙权&#xff1f;, value: 错…

算法设计与分析第一周题目

Leetcode 4.寻找两个正序数组的中位数 题目描述&#xff1a; 给定两个大小分别为 m 和 n 的正序&#xff08;从小到大&#xff09;数组 nums1 和 nums2。请你找出并返回这两个正序数组的中位数 。 算法的时间复杂度应该为 O(log (mn)) 。 解法1&#xff1a;先排序再查找 先…

上海建筑模板厂家:承载城市梦想的力量

上海&#xff0c;作为中国最具国际化和现代化的城市之一&#xff0c;拥有令人瞩目的建筑风貌和繁荣的建筑业。在这座充满活力的城市里&#xff0c;建筑模板作为建筑施工的重要组成部分&#xff0c;发挥着不可或缺的作用。而上海建筑模板厂家作为支撑城市发展的重要力量&#xf…

北大硕士7年嵌入式学习经验分享

阶段 1 大一到大三这个阶段我与大多数学生相同&#xff1a; 学习本专业知识&#xff08;EE专业&#xff09;&#xff0c;学习嵌入式软件开发需要的计算机课程&#xff08;汇编原理&#xff0c;计算机组成原理&#xff0c;操作系统&#xff0c;C语言等&#xff09;&#xff0c…

Git使用【中】

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;那个传说中的man的主页 &#x1f3e0;个人专栏&#xff1a;题目解析 &#x1f30e;推荐文章&#xff1a;题目大解析3 目录 &#x1f449;&#x1f3fb;分支管理分支概念git branch&#xff08;查看/删除分…

MacOS怎么安装Nacos(附带:Windows系统)

MacOS安装Nacos&#xff08;一定要配置JDK的环境变量&#xff0c;后面告诉你为什么&#xff1f;&#xff09; &#xff08;1&#xff09;进入Nacos官网&#xff0c;前往githubhomehomehttp://nacos.io/zh-cn/ &#xff08;2&#xff09;点击右下角的releases 然后点击Tags 选择…

【算法】排序——选择排序和交换排序(快速排序)

主页点击直达&#xff1a;个人主页 我的小仓库&#xff1a;代码仓库 C语言偷着笑&#xff1a;C语言专栏 数据结构挨打小记&#xff1a;初阶数据结构专栏 Linux被操作记&#xff1a;Linux专栏 LeetCode刷题掉发记&#xff1a;LeetCode刷题 算法头疼记&#xff1a;算法专栏…

React18入门(第一篇)——JSX、TSX语法详解

文章目录 一、JSX 语法简介二、和 HTML 标签的几点不同三、JSX 属性四、JSX 事件4.1 简单点击事件4.2 类型限制4.3 带参数&#xff0c;箭头函数 五、插入 JS 变量六、JSX 中使用条件判断七、循环 一、JSX 语法简介 JSX - 是 JS 的扩展&#xff0c;写在 JS 代码里面&#xff0c…

【Docker】Docker的应用包含Sandbox、PaaS、Open Solution以及IT运维概念的详细讲解

前言 Docker 是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。 &#x1f4d5;作者简介&#xff1a;热…

Windows下Tensorflow docker python开发环境搭建

前置条件 windows10 更新到较新的版本&#xff0c;硬件支持Hyper-V。 参考&#xff1a;https://learn.microsoft.com/zh-cn/windows/wsl/install 启用WSL 在Powershell中输入如下指令&#xff1a; dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsys…

数据挖掘(2)数据预处理

一、数据预处理 1.1概述 数据预处理的重要性 杂乱性&#xff1a;如命名规则。重复性&#xff1a;同一客观事再不完整性&#xff1a;噪声数据&#xff1a;数据中存在错误或异常的现象。 数据预处理的常见方法 数据清洗&#xff1a;去掉数据中的噪声&#xff0c;纠正不一致。数…

【C语言】循环结构程序设计 (详细讲解)

前言&#xff1a;前面介绍了程序中常常用到的顺序结构和选择结构&#xff0c;但是只有这两种结构是不够的&#xff0c;还有用到循环结构(或者称为重复结构)。因为在日常生活中或是在程序所处理的问题中常常遇到需要重复处理的问题。 【卫卫卫的代码仓库】 【选择结构】 【专栏链…

C语言数组和指针笔试题(五)(一定要看)

这里写目录标题 指针运算笔试题解析题目1解析结果 题目2解析结果 题目3解析结果 题目4解析结果 题目5解析结果 题目6解析结果 题目7解析结果 题目8解析结果 感谢各位大佬对我的支持,如果我的文章对你有用,欢迎点击以下链接 &#x1f412;&#x1f412;&#x1f412;个人主页 &a…

【智能家居项目】裸机版本——设备子系统(LED Display 风扇)

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《智能家居项目》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 输入子系统中目前仅实现了按键输入&#xff0c;剩下的网络输入和标准输入在以后会逐步实现&am…