自己编写的DAL三层代码生成器

(1)创建自己的解决方案 目录结构如下:

(2)编写代码:

(要使用数据库 建议创建任意数据库即可)

创建配置文件App.config代码如下:

<?xml version="1.0"?>
<configuration>
  <connectionStrings>
    <add name="connstr" connectionString="Data Source=.; Initial Catalog=HRMSYSDB;User ID=hrmsa;Password=你的数据库密码"/>
  </connectionStrings>
  <appSettings>
    <add key="passwordSalt" value="[email protected]"/>
    <add key="aaa" value="333"/>
  </appSettings>

</configuration>

MainWindow.xaml代码如下:(在MainWindow.xaml下把Grid里边的代码换一下就好了)

<Grid>
        <TextBox Height="23" HorizontalAlignment="Left" Margin="16,7,0,0" Name="txtConnStr" VerticalAlignment="Top" Width="542" />
        <Button Content="连接" Height="23" HorizontalAlignment="Left" Margin="564,7,0,0" Name="btnConnect" VerticalAlignment="Top" Width="41" Click="btnConnect_Click" />
        <ComboBox Height="23" HorizontalAlignment="Left" Margin="16,36,0,0" Name="cmbTables" VerticalAlignment="Top" Width="210" IsEnabled="False" />
        <Button Content="生成代码" Height="23" HorizontalAlignment="Left" Margin="244,36,0,0" Name="btnGenerateCode" VerticalAlignment="Top" Width="75" IsEnabled="False" Click="btnGenerateCode_Click" />
        <TextBox TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" Height="483" HorizontalAlignment="Left" Margin="16,66,0,0" Name="txtModelCode" VerticalAlignment="Top" Width="342" IsReadOnly="True" />
        <TextBox TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" Height="483" HorizontalAlignment="Left" Margin="372,66,0,0" Name="txtDALCode" VerticalAlignment="Top" Width="494" IsReadOnly="True" />
    </Grid>

MainWindow.xaml.cs代码如下:

namespace MyCodeGen //这里要把命名空间改成自己的 也就是自己生成的   只需粘贴<span style="font-family: Arial, Helvetica, sans-serif;">public partial class MainWindow : Window{  下边的内容即可</span>

{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private DataTable ExecuteDataTable(string sql)
        {
            using (SqlConnection conn = new SqlConnection(txtConnStr.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 btnConnect_Click(object sender, RoutedEventArgs 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"];
            }
            cmbTables.ItemsSource = tables;
            cmbTables.IsEnabled = true;
            btnGenerateCode.IsEnabled = true;

            //把连接字符串记录到文件中,避免用户每次都需要输入连接字符串
            //File.WriteAllText("connstr.txt", txtConnStr.Text); //默认保存为自己工作目录下

            //string currenctDir = AppDomain.CurrentDomain.BaseDirectory//获得当前程序的文件夹,最稳定
            //string configFile = currenctDir + "connstr.txt";

            //将连接字符串保存起来
            string configFile = GetConfigFilePath();
            File.WriteAllText(configFile, txtConnStr.Text);

            //除非真的有捕获异常的需要,否则不要try...catch
        }

        //为例避免每次都输入链接数据库字符串 将保存的代码封装到函数中
        private static string GetConfigFilePath()
        {
            string currenctDir = AppDomain.CurrentDomain.BaseDirectory;
            string configFile = System.IO.Path.Combine(currenctDir, "connstr.txt");
            return configFile;
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            //在每次加载的时候都要加载  保存在文件夹内的 连接字符串
            string configFile = GetConfigFilePath();
            txtConnStr.Text = File.ReadAllText(configFile);
        }

        private void btnGenerateCode_Click(object sender, RoutedEventArgs e)
        {
            string tablename = (string)cmbTables.SelectedItem;
            if (tablename == null)
            {
                MessageBox.Show("请选择要生成的表");
                return;
            }
            CreateModelCode(tablename);
            CreateDALCode(tablename);
        }

        private void CreateModelCode(string tablename)
        {
            //bool b = true;//bool和System.Boolean是同一个东西
            //System.Boolean b1 = true;//CTS
            //System.String s1 = "";
            //string s2 = "";    

            DataTable table = ExecuteDataTable("select top 0 * from "
                + tablename);
            //在大量的字符串拼接的时候使用stringbuilder()
            StringBuilder sb = new StringBuilder();
            sb.Append("public class ").AppendLine(tablename).AppendLine("{");
            foreach (DataColumn column in table.Columns)
            {
                string columnDataType = GetDataTypeName(column); //判断类型是否可空
                sb.Append("    ").Append("public ").Append(columnDataType).Append(" ")
                    .Append(column.ColumnName).AppendLine("{get;set;}");
            }
            sb.AppendLine("}");
            txtModelCode.Text = sb.ToString();
        }

        //进行可空类型的处理
        private static string GetDataTypeName(DataColumn column)
        {
            //如果列允许为null,并且列在C#中的类型是不可为空的(值类型ValueType)
            if (column.AllowDBNull && column.DataType.IsValueType)
            {
                return column.DataType + "?";
            }
            else
            {
                return column.DataType.ToString();
            }
        }

        //下边是生成DALcode部分
        private void CreateDALCode(string tablename)
        {
            DataTable table = ExecuteDataTable("select top 0 * from "
                + tablename);
            StringBuilder sb = new StringBuilder();
            sb.Append("public class ").Append(tablename).AppendLine("DAL").AppendLine("{");

            //tomodel开始
            sb.Append("    ").Append("private ").Append(tablename)
                .AppendLine(" ToModel(DataRow row)").Append("    ").AppendLine("{");
            sb.Append("        ").Append(tablename).AppendLine(" model = new " + tablename + "();");
            foreach (DataColumn column in table.Columns)
            {
                //无论列是否允许为空,都进行判断DbNull的处理(省事)
                //model.Id = (Guid)SqlHelper.FromDbValue(row["Id"]);
                sb.Append("        ").Append("model.").Append(column.ColumnName).Append("=(")
                    .Append(GetDataTypeName(column)).Append(")SqlHelper.FromDbValue(row[\"")
                   .Append(column.ColumnName).AppendLine("\"]);");
            }
            sb.Append("        ").AppendLine("return model;");
            sb.AppendLine("}");
            //tomodel的结束

            //listall开始
            //public IEnumerable<Department> ListAll()
            sb.Append("public IEnumerable<").Append(table)
                .AppendLine("> ListAll()").AppendLine("{");
            //List<Department> list = new List<Department>();
            sb.Append("    ").Append("List<").Append(tablename).Append("> list=new List<")
                .Append(tablename).AppendLine(">();");
            // DataTable dt = SqlHelper.ExecuteDataTable
            //("select * from T_Department");
            sb.Append("DataTable dt = SqlHelper.ExecuteDataTable(\"")
                .Append("select * from " + tablename).AppendLine("\");");
            sb.AppendLine("foreach (DataRow row in dt.Rows)");
            //Department dept = ToModel(row);
            sb.Append(tablename).AppendLine(" model=ToModel(row);");
            //list.Add(model);
            sb.AppendLine("list.Add(model);}");

            sb.AppendLine("}");
            //listall结束

            //GetById();
            //DeleteById();

            //生成器要求列名必须是Id,类型必须是Guid

            //Insert开始
            //public void Insert(Operator op)
            sb.Append("public void Insert(")
                .Append(tablename).AppendLine(" model){");
            //SqlHelper.ExecuteNonQuery(@"insert into T_Operator(
            sb.Append("SqlHelper.ExecuteNonQuery(@\"")
                .Append("insert into ").Append(tablename).AppendLine("(");
            string[] colNames = GetColumnNames(table);
            sb.AppendLine(string.Join(",", colNames));
            string[] colParamNames = GetParamColumnNames(table);
            sb.Append("values(").AppendLine(string.Join(",", colParamNames));
            sb.AppendLine("}");
            //Insert结束

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

        //以数组形式返回列名
        private static string[] GetColumnNames(DataTable table)
        {
            string[] colnames = new string[table.Columns.Count];
            for (int i = 0; i < table.Columns.Count; i++)
            {
                DataColumn dataCol = table.Columns[i];
                colnames[i] = dataCol.ColumnName;
            }
            return colnames;
        }

        //以数组形式返回@列名
        private static string[] GetParamColumnNames(DataTable table)
        {
            string[] colnames = new string[table.Columns.Count];
            for (int i = 0; i < table.Columns.Count; i++)
            {
                DataColumn dataCol = table.Columns[i];
                colnames[i] = "@" + dataCol.ColumnName;
            }
            return colnames;
        }
    }
}

SqlHelper.cs代码如下:(命名空间里边的代码)

static class SqlHelper
    {
        //app.config文件的继承:

        public static readonly string connstr =
            ConfigurationManager.ConnectionStrings["connstr"].ConnectionString;//别忘了添加引用 System.configuration 然后在解析到<pre name="code" class="csharp"><span style="white-space:pre">	</span>//ConfigurationManager   步骤:右键点击引用--添加引用--.NET--找到<span style="font-family: Arial, Helvetica, sans-serif;">System.configuration 确定即可</span>

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 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 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); DataSet dataset = new DataSet(); SqlDataAdapter adapter = new SqlDataAdapter(cmd); adapter.Fill(dataset); return dataset.Tables[0]; } } //try //{ //} //catch //{ // DataTable
dt = new DataTable(); // return dt; //} } 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; } } }


好了 全部代码都好了!点击运行效果如下:

另外需要完整项目的请点击:

http://download.csdn.net/detail/u010870518/7837691

如果导入数据库mdf不熟悉的请参考:

http://blog.csdn.net/xlgen157387/article/details/38844315

时间: 2024-10-13 14:09:24

自己编写的DAL三层代码生成器的相关文章

自己动手写三层代码生成器学习总结

一.三层代码生成器关键:数据库的重要视图 今天看了下老杨的视频教程,写了一把三层代码生成器,理解了一下简单的代码生成器是如何实现的,其重点就在于数据库系统视图. 代码生成器需要了解数据库中的几个非常重要的视图,比如INFORMATION_SCHEMA(.TABLES..COLUMNS)以及一些类型属性Data_Type,Column_Name等.然后利用模板,通过StringBulider来进行字符串的拼接,也就是AppendLine()方法.当然,其中涉及到SQL方法封装.数据库类型向.NET

三层架构理论总结

What? 三层架构就是将整个业务应用划分为:表示层(Presentation Layer).业务逻辑层(Business Logic Layer).数据访问层(Data Access Layer). Why? 区分层次的目的是实现"高内聚,低耦合"的思想.三层结构是软件架构设计中,最普遍的一种结构. When? 当有数据访问以及业务逻辑的时候就要考虑使用三层结构了,此三层结构是按逻辑划分的.把数据访问脱离业务单独存在,把业务脱离开界面单独存在. 当数据逻辑简单,没有数据存储层,不需要

20.代码生成器

(这一节并不是特别懂,尤其是主动代码生成器) 当需要编写的功能存在于不同的语境,不同的位置时,我们为了避免重复的码字,减少不必要的重复劳动,这时我们就需要构件代码生成器. *编写可以编写代码的代码 代码生成器分为两种: 1.被动代码生成器 只运行一次来生成代码,而后的生成的结果与代码生成器就完全分离,没有任何的关系了. 被动代码生成器减少敲键次数.实际上是参数化模板.根据输入的参数,输出给定格式的最终结果.(例如:web应用中的前端模板文件,参数就是模板中将被动态语言替换掉的数据,模板文件就相当

c#笔试基础(转载)

技术类面试.笔试题汇总 注:标明*的问题属于选择性掌握的内容,能掌握更好,没掌握也没关系. 下面的参考解答只是帮助大家理解,不用背,面试题.笔试题千变万化,不要梦想着把题覆盖了,下面的题是供大家查漏补缺用的,真正的把这些题搞懂了,才能“以不变应万变”.回答问题的时候能联系做过项目的例子是最好的,有的问题后面我已经补充联系到项目中的对应的案例了. 1.简述 private. protected. public. internal 修饰符的访问权限. private : 私有成员, 在类的内部才可以

跟着杨中科循序渐进学习wpf(全)

第一季 C#编程基础 1.用C#编写一个10+20=?的小程序: public static voidMain(tring[] args) { int i1=10; int i2=20; int i3=i1+i2; Console.WriteLine(i3);           //也可用占位符来实现:Console.WriteLine("{0}+{1}={2}",i1,i2,i1+i2);在输出参数较多时候要用占位符 Console.ReadKey();             

.net主要题型积累

1.简述 private. protected. public. internal 修饰符的访问权限. private : 私有成员, 在类的内部才可以访问. protected : 保护成员,该类内部和继承类中可以访问. public : 公共成员,完全公开,没有访问限制. internal: 当前程序集内可以访问. 2.ADO.NET中的五个主要对象 Connection:主要是开启程序和数据库之间的连接.没有利用连接对象将数据库打开,是无法从数据库中取得数据的.Close和Dispose的

C#笔试面试宝典值得收藏1

技术类面试.笔试题汇总 注:标明*的问题属于选择性掌握的内容,能掌握更好,没掌握也没关系. 下面的参考解答只是帮助大家理解,不用背,面试题.笔试题千变万化,不要梦想着把题覆盖了,下面的题是供大家查漏补缺用的,真正的把这些题搞懂了,才能“以不变应万变”.回答问题的时候能联系做过项目的例子是最好的,有的问题后面我已经补充联系到项目中的对应的案例了. 1.简述 private. protected. public. internal 修饰符的访问权限. private : 私有成员, 在类的内部才可以

.NET工程师面试宝典

.Net工程师面试笔试宝典 传智播客.Net培训班内部资料 这套面试笔试宝典是传智播客在多年的教学和学生就业指导过程中积累下来的宝贵资料,大部分来自于学员从面试现场带过来的真实笔试面试题,覆盖了主流的.Net笔试面试题.很多学员面试回来都会说“这次面试出的题几乎都在面试笔试宝典上有”,比如下面就是一个老学员的来信: 这套面试题主要目的是帮助那些还没有.Net软件开发实际工作经验,而正在努力寻找.Net软件开发工作的朋友在笔试时更好地赢得笔试和面试.由于这套面试题涉及的范围很泛,很广,很杂,大家不

2019面试宝典之.Net

1.简述 private. protected. public. internal 修饰符的访问权限. private : 私有成员, 在类的内部才可以访问. protected : 保护成员,该类内部和继承类中可以访问. public : 公共成员,完全公开,没有访问限制. internal: 当前程序集内可以访问. 2.ADO.NET中的五个主要对象 Connection:主要是开启程序和数据库之间的连接.没有利用连接对象将数据库打开,是无法从数据库中取得数据的.Close和Dispose的