自制代码生成器

                                                                                         

  在敲机房收费系统的时候,由于用三层的思想时须要用到实体类。最麻烦的是不断的来定义实体的属性值,真实烦人。想一想有没有好的方法来操作呢?


  注意:实体的属性是与数据库中表的字段是相互相应的。


  从网上查资料发现了代码生成器这个好东西。网上有免费的,大家能够学习一下,以后在做的时候就方便多了,可是更重要的是要知道原理,即本质。在这里小编就教大家来自制代码生成器,最简陋的操作,意在告诉大家代码生成器背后的原理。

image


代码例如以下

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;



namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }


        /// <summary>
        /// 连接数据库操作
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        private DataTable ExecuteDataTable(string sql)
        {
            using (SqlConnection conn = new SqlConnection(textBox1 .Text ))
            {
                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);
                    return ds.Tables[0];
                }




            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //查询出连接的数据库中全部表的名字
            DataTable table;
            try 
            {
                //查询语句,用来查询数据库中表的名字
               table = ExecuteDataTable("select table_name from INFORMATION_SCHEMA.tables  where table_type ='base table'");

            }
                //当发生连接错误时。抛出异常
           catch (SqlException sqlex )
            {
                MessageBox.Show("连接数据库出错!错误信息:" + sqlex.Message);
                return;
            }

            
                //用来存储每张表的名字
            string[] tables=new string[table.Rows.Count ];


            //通过遍历来为字符串数组赋值
            for(int i=0;i<table.Rows.Count ;i++)
            {
                DataRow row=table.Rows[i];
                tables[i]=(string )row["table_name"];

            }
            comboBox1.DataSource  = tables;
            comboBox1.Enabled = true;

            //把连接字符串记录到文件里。避免用户每次都须要输入连接字符串
           // File.WriteAllText("",textBox1 .Text )
               // AppDomain.CurrentDomain .BaseDirectory //获得当前程序的路径
                  //string currentDir=AppDomain.CurrentDomain .BaseDirectory ;
            //string configFile=currentDir +"textbox1.txt"
            //用来拼接当前文件夹的路径
                  string configFile = GetConfigFilePath();
          //保存写入的字符串
            File.WriteAllText (configFile ,textBox1 .Text );
        }



        //封装保存字符串的路径
        private static string GetConfigFilePath()
        {
            //获得当前程序的路径
            string currentDir = AppDomain.CurrentDomain.BaseDirectory;
          //用来拼接路径
            string configFile = System.IO.Path.Combine(currentDir, "textbox1.text");
            return configFile;  //返回拼接的路径
        }

       /// <summary>
       /// 用来读出保存的路径
       /// </summary>
       /// <param name="sender"></param>
       /// <param name="e"></param>
        private void Form1_Load(object sender, EventArgs e)
        {
            string configFile = GetConfigFilePath();
          textBox1 .Text =  File.ReadAllText(configFile);

        }

        private void button2_Click(object sender, EventArgs e)
        {
            //得到选择的表的名字
            string tablename = (string )comboBox1.SelectedItem;
            if(tablename =="")
            {
                MessageBox.Show("请选择要生成的表");
                return;
            }
            CreateModelCode(tablename);
        }

        private void CreateModelCode(string tableName)
        {
            //选择查询表的表头
            DataTable table = ExecuteDataTable("select top 0 * from "+tableName);
                //拼接字符串类
             StringBuilder sb = new StringBuilder();
            //定义类,此时类的名字就是表的名字,须要时能够随时更改
                sb.Append("public class").Append(tableName).AppendLine("{"); 
            
            //開始声明属性的名字
            foreach (DataColumn column in table.Columns )
            {
                //得到类的类型
                string columnDataType = GetDateTypeName(column);
                //定义属性
                sb.Append("public").Append(columnDataType ).Append("")
                    .Append(column.ColumnName).AppendLine("{get;set}");
         
            }
            sb.AppendLine("}");
            textBox2.Text = sb.ToString();
        }


        //进行可空类型的推断
        private static string GetDateTypeName(DataColumn column)
        {
            //假设列执行为NULL,而且列在C#中的类型是不可为空的(值类型)
            if(column.AllowDBNull&&column.DataType.IsValueType   )
            {
                return column.DataType + "?";
            }
            else
            {
                return column.DataType.ToString ();
            }
        }


    }
}


功能介绍

1.输入连接字符串

2.选择要生成代码的表

3.生成代码

 

原理介绍

1.依据字符串获取全部表名

select table_name from INFORMATION_SCHEMA.tables  where table_type ='base table'

2.通过运行select操作,得到的column的类型,列名等,还须要推断是否为空等信息

3.通过stringbuilder来完毕字符串的拼接


小结:不怕不知道,就怕不知道,事实上没有什么牛X的技术,就是通过查询数据库中的表名。然后通过查询列的属性等信息,通过遍历来完毕所要实现的属性的拼接已。

-------------------------------------------------------聪明的程序猿永远都有偷懒的办法-----------------------------------------------------



posted @ 2017-07-18 12:55  jzdwajue  阅读(829)  评论(0编辑  收藏  举报