前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >代码生成器原理及示例

代码生成器原理及示例

作者头像
全栈程序员站长
发布2022-07-25 10:33:02
9260
发布2022-07-25 10:33:02
举报
文章被收录于专栏:全栈程序员必看

大家好,又见面了,我是你们的朋友全栈君。

在三层架构中Model、DAL(Data Access Layer)、BLL层有必要分开,其中有些代码可以由代码生成器生成。虽然网络已经有成熟的代码生成器,但是第三方代码生成器在实际应用场景中,生成的代码经常还需要在其基础上修改。修改其代码就不如修改代码生成器本身。所以掌握代码生成器的编写方法、原理还是很有必要的。

下面通过一个例子简要介绍代码生成器编写过程,并给出一个具备基本功能的范例雏形。以抛砖引玉。

成果展示截图:

代码生成器原理及示例
代码生成器原理及示例

图 代码生成器界面截图

代码生成器原理及示例
代码生成器原理及示例

DAL结果截图

代码生成器原理及示例
代码生成器原理及示例

Model截图

后台代码展示如下:

代码语言:javascript
复制
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Configuration;
using System.Data.SqlClient;


namespace 我的代码生成器
{
    public partial class FormCodeGenerater : Form
    {
        public FormCodeGenerater()
        {
            InitializeComponent();
        }
     

        /// <summary>
        /// 使用ConfigurationManager读取App.config中的字符串。
        /// </summary>
        static string connStr = ConfigurationManager.ConnectionStrings["dbConnStr"].ConnectionString;

        #region 方法
        /// <summary>
        /// 获取数据库中所有的字段名称
        /// </summary>
        private List<string> GetFields(string _connectString, string _tableName)
        {
            List<string> tableNameList = new List<string>();
            using (SqlConnection conn = new SqlConnection(connStr))
            {
                conn.Open();
                using (SqlCommand cmd = conn.CreateCommand())
                {
                    cmd.CommandText = "select * from " + _tableName;
                    DataSet ds = new DataSet();
                    SqlDataAdapter adapter = new SqlDataAdapter(cmd);
                    adapter.FillSchema(ds, SchemaType.Source);
                    adapter.Fill(ds);

                    DataTable table = ds.Tables[0];
                    foreach (DataColumn col in table.Columns)
                    {
                        string tmpString = col.ColumnName + "," + col.AllowDBNull + "," + col.DataType;
                        tableNameList.Add(tmpString);
                    }
                }
            }
            return tableNameList;
        }

        /// <summary>
        /// 获取数据库表名
        /// </summary>
        /// <param name="_connectString"></param>
        /// <returns></returns>
        private List<string> GetTableNames(string _connectString)
        {
            List<string> resultList = new List<string>();
            string databaseName = GetDataBaseNameFromConnectString(_connectString);//todo 取出数据库名称
            //string.take
            string sql = "SELECT Name FROM " + databaseName + "..SysObjects Where XType='U' ORDER BY Name";
            DataTable dt = ExecuteDataTable(_connectString, sql);
            //todo装载resultList
            foreach (DataRow row in dt.Rows)
            {
                string tmpString = row[0].ToString();
                resultList.Add(tmpString);
            }
            return resultList;
        }

        /// <summary>
        /// 从连接字符串读取出数据库名称
        /// </summary>
        /// <returns></returns>
        private string GetDataBaseNameFromConnectString(string _connectString)
        {
            try
            {
                string[] strArray = _connectString.Split(';');
                string resultStr = strArray[1].Substring(16);
                return resultStr;
            }
            catch { return string.Empty; }
        }

        /// <summary>
        /// 执行sql语句,返回datatable
        /// </summary>
        /// <param name="_connectString"></param>
        /// <param name="sql"></param>
        /// <returns></returns>
        private DataTable ExecuteDataTable(string _connectString, string sql)
        {
            using (SqlConnection conn = new SqlConnection(_connectString))
            {
                conn.Open();
                using (SqlCommand cmd = conn.CreateCommand())
                {
                    cmd.CommandText = sql;
                    DataSet ds = new DataSet();
                    SqlDataAdapter adapter = new SqlDataAdapter(cmd);
                    adapter.FillSchema(ds, SchemaType.Source);
                    adapter.Fill(ds);

                    DataTable table = ds.Tables[0];
                    return table;
                }
            }
        }

        /// <summary>
        ///  如果列允许为null,并且列在c#中的类型是不可空的(值类型)
        /// </summary>
        /// <param name="_column"></param>
        /// <returns></returns>
        private static string GetDataTypeName(DataColumn _column)
        {
            //如果列允许为null,并且列在c#中的类型是不可空的(值类型)
            if (_column.AllowDBNull && _column.DataType.IsValueType)
            {
                return _column.DataType + "?";
            }
            else
            {
                return _column.DataType.ToString();
            }
        }
        #endregion


        #region 事件
        private void FormCodeGenerater_Load(object sender, EventArgs e)
        {
            textBoxConnStr.Text = connStr;
        }

        private void buttonConnect_Click(object sender, EventArgs e)
        {
            try
            {
                //绑定Combobox
                comboBoxTables.Items.Clear();
                List<string> TableNameList = GetTableNames(connStr);
                comboBoxTables.Items.AddRange(TableNameList.ToArray());
                if (comboBoxTables.Items.Count > 0)
                    comboBoxTables.SelectedIndex = 0;
                buttonGenerateCode.Enabled = true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        private void buttonGenerateCode_Click(object sender, EventArgs e)
        {
            string tableName = (string)comboBoxTables.SelectedItem;
            if (tableName == null)
            {
                MessageBox.Show("请选择要生成的表");
                return;
            }
            //大量字符串拼接,需要使用StringBuilder效率更高
            //Append()拼接
            //AppendLine()后面加一行

            CreateModelCode(connStr,tableName);
            CreateDALCode(connStr, tableName);
        }

        private void CreateModelCode(string _connStr,string _tableName)
        {
            DataTable table = ExecuteDataTable(_connStr, "select top 0 * from " + _tableName);
            StringBuilder sb = new StringBuilder();
            sb.Append("public class ").Append(_tableName).AppendLine("{");
            foreach (DataColumn col in table.Columns)
            {
                sb.Append("     public ").Append(GetDataTypeName(col)).Append(" ")
                    .Append(col.ColumnName).AppendLine("{get;set;}");             
            }
            sb.AppendLine("}");

            richTextBoxModelCode.Text = sb.ToString();
        }

        /// <summary>
        /// 创建DAL代码
        /// </summary>
        /// <param name="_tableName"></param>
        private void CreateDALCode(string _connStr, string _tableName)
        {
            string blanksString = "   ";
            DataTable table = ExecuteDataTable(_connStr, "select top 0 * from " + _tableName);
            StringBuilder sb = new StringBuilder();
            sb.Append("public class ").Append(_tableName).AppendLine("DAL").AppendLine("{");
 
            //ToModel开始
            sb.Append("   private ").Append(_tableName).AppendLine(" ToModel(DataRow row)").Append(blanksString + "{");
            sb.Append(blanksString + _tableName).AppendLine(" model=new " + _tableName + "();");
            foreach (DataColumn col in table.Columns)
            {
                //无论列是否为空,都进行判断DbNull的处理
                //model.Id=(Guid)SqlHelper.FromDbValue(row["Id"]);
                // \表示转义字符
                sb.Append(blanksString+"model.").Append(col.ColumnName).Append("=(").Append(GetDataTypeName(col)).Append(")SqlHelper.FromDbValue(row[\"").Append(col.ColumnName).AppendLine("\"]);");
            }
            sb.Append("return model;").AppendLine("}");

            //ToModel的结束
            //ListAll开始
            //public IEnumerable<Department> ListAll()
            sb.Append("public IEnumerable<").Append(_tableName).AppendLine("> ListAll()");
            sb.AppendLine("{");
            sb.Append(blanksString+"List<").Append(_tableName).Append("> list=new List<").Append(_tableName).AppendLine(">();");
            sb.Append(blanksString+"DataTable dt=SqlHelper.ExecuteDataTable(\"").Append("select * from "+_tableName).AppendLine("\");");
            sb.AppendLine("foreach(DataRow row in dt.Rows)");
            sb.Append("{");
            sb.Append(_tableName).Append(" model=ToModel(row);");
            sb.AppendLine("list.Add(model);}");
            sb.AppendLine("return list;");
            sb.AppendLine("}");
            //ListAll结束

            
            sb.AppendLine(blanksString + "public static object FromDbValue(object value)");
            sb.AppendLine(blanksString+"{");
            sb.Append(blanksString+"  if (value == DBNull.Value)");
            sb.AppendLine(blanksString+"  {return null;}");
            sb.Append("else");
            sb.AppendLine(blanksString + "  {return value;}");
            sb.AppendLine(blanksString+"}");

            //FromDbValue()结束



            sb.AppendLine("}");
            richTextBoxDALCode.Text = sb.ToString();
        }

        /// <summary>
        /// 以数组形式返回列名。
        /// </summary>
        /// <param name="_table"></param>
        /// <returns></returns>
        private static string[] GetParamColumnNames(DataTable _table)
        {
            string[] colNames = new string[_table.Columns.Count];
            for (int i = 0; i < colNames.Count(); i++)
            {
                 DataColumn dataCol=_table.Columns[i];
                 colNames[i] ="@"+ dataCol.ColumnName;
            }
            return colNames;
        }
        /// <summary>
        /// 以数组形式返回列名。
        /// </summary>
        /// <param name="_table"></param>
        /// <returns></returns>
        private static string[] GetColumnNames(DataTable _table)
        {
            string[] colNames = new string[_table.Columns.Count];
            for (int i = 0; i < colNames.Count(); i++)
            {
                DataColumn dataCol = _table.Columns[i];
                colNames[i] =  dataCol.ColumnName;
            }
            return colNames;
        }
  
        #endregion

    }
}

将连接字符串存储到App.Config中

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <connectionStrings>
    <add name="dbConnStr" connectionString="Data Source=xxx.xxx.xx.xx,xxxx;Initial Catalog=LightningScienceAndTechnology;User ID=xx;Password=xxxxxxxxxx"/>
  </connectionStrings>
</configuration>

SqlHelper相关代码

代码语言:javascript
复制
 public class SqlHelper
    {

       static  string connStr = ConfigurationManager.ConnectionStrings["dbConnStr"].ConnectionString;

        public static object ExecuteScalar(string sql, params SqlParameter[] parameters)
        {
            using (SqlConnection conn = new SqlConnection(connStr))
            {
                conn.Open();
                using (SqlCommand cmd = conn.CreateCommand())
                {
                    cmd.CommandText = sql;
                    cmd.Parameters.AddRange(parameters);
                    return cmd.ExecuteScalar();
                }
            }
        }

        public static int ExecuteNonQuery(string sql, params SqlParameter[] parameters)
        {
            using (SqlConnection conn = new SqlConnection(connStr))
            {
                conn.Open();
                using (SqlCommand cmd = conn.CreateCommand())
                {
                    cmd.CommandText = sql;
                    cmd.Parameters.AddRange(parameters);
                    return cmd.ExecuteNonQuery();
                }
            }
 
        }

        public static DataTable ExecuteDataTable(string sql, params SqlParameter[] parameters)
        {
            using (SqlConnection conn = new SqlConnection(connStr))
            {
                conn.Open();
                using (SqlCommand cmd =conn.CreateCommand())
                {
                    cmd.CommandText = sql;
                    cmd.Parameters.AddRange(parameters);

                    SqlDataAdapter sqlAdapter = new SqlDataAdapter(cmd);
                    DataSet ds = new DataSet();
                    sqlAdapter.Fill(ds);
                    return ds.Tables[0];
                }
            }
        }

        public static object FromDbValue(object value)
        {
            if (value == DBNull.Value)
            {
                return null;
            }
            else
            {
                return value;
            }
        }

        public static object ToDbValue(object value)
        {
            if (value == null)
            {
                return DBNull.Value;
            }
            else
            {
                return value;
            }
        }
    }

注意事项:

1 StringBuilder字符串拼接,在大量字符串拼接的情况下,效率比”+”要高。

2 在Model中考虑到可空类型(比如:int?)

3 app.Config的读取需要引用System.Configuration

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/127021.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年4月9,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档