自制代码生成器

news/2024/7/24 12:41:34 标签: 数据库, c#

                                                                                         

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


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


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

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的技术,就是通过查询数据库中的表名。然后通过查询列的属性等信息,通过遍历来完毕所要实现的属性的拼接已。

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




转载于:https://www.cnblogs.com/jzdwajue/p/7199939.html


http://www.niftyadmin.cn/n/1090110.html

相关文章

Linux基础命令---显示树形进程pstree

pstree pstree显示正在运行的进程的树形结构&#xff0c;树以PID为根&#xff1b;如果省略了pid则以init为根。如果指定了用户名&#xff0c;则显示根植于该用户拥有的进程的所有进程树。如果pstree被调用为pstree.x11&#xff0c;那么它将提示行尾的用户按RETURE&#xff0c;并…

sql操作一般函数

sql操作一般函数 函数一般语法&#xff1a;SELECT function(列) FROM 表 函数的基本类型是&#xff1a; Aggregate 合计函数&#xff1a;函数的操作面向一系列的值&#xff0c;并返回一个单一的值。 Scalar 函数&#xff1a;操作面向某个单一的值&#xff0c;并返回基于输入值的…

mybatis 关于 if test 判断字符串的大坑

https://blog.csdn.net/chenaini119/article/details/51917263 还有XML文件 不能用> <来表达大于小于 。。 例如 grade>0 , grade<10 https://blog.csdn.net/zheng0518/article/details/10449549 老周一直遇到的bug 今天遇到的一个数据查询 的难题 就是统计 评价当…

解决Oracle XDB与Tomcat等的8080端口的冲突

【IT168 服务器学院】从9i 开始&#xff0c;oracle的安装缺省包含了XDB。在数据库后&#xff0c;Oracle XDB的http服务自动霸占了8080端口&#xff0c;这给使用或JBoss、Tomcat进行java web开发的人造成了不小的麻烦。 这里介绍修改XDB的http和ftp服务端口的3种方法&#xff1a…

Linux基础命令---显示进程ps

ps ps指令可以显示系统中当前进程的信息&#xff0c;它的输出结果是高度可定制的。如果您希望重复更新所选内容和显示的信息&#xff0c;请使用top(1)代替。 请注意&#xff0c;“ps-aux”与“ps aux”不同。POSIX和UNIX标准要求“ps-aux”打印名为“x”的用户拥有的所有进程&a…

使用HttpClient MultipartEntityBuilder 上传文件,并解决中文文件名乱码问题

遇到一种业务场景&#xff0c;前端上传的文件需要经过java服务转发至文件服务。期间遇到了原生HttpClient怎么使用的问题、怎么把MultipartFile怎么重新组装成Http请求发送出去的问题、文件中文名乱码问题。最后都解决了&#xff0c;先上代码&#xff0c;再讲遇到的坑 1 Slf4j2…

POJ 2456 Aggressive cows ( 二分搜索)

题目链接 Description Farmer John has built a new long barn, with N (2 < N < 100,000) stalls. The stalls are located along a straight line at positions x1,...,xN (0 < xi < 1,000,000,000). His C (2 < C < N) cows dont like this barn layout a…

DRF框架QQ登录功能

用户模块---QQ登录 流程图 QQ登录文档:http://wiki.connect.qq.com/%E5%87%86%E5%A4%87%E5%B7%A5%E4%BD%9C_oauth2-0 流程简述: 1.当点击qq登录图标时,进入生成登录url的接口 2.在前端的回调函数中跳转到qq登录的扫码页面 3.扫码登陆后,qq会携带code访问申请时指定的回调地址,…