zoukankan      html  css  js  c++  java
  • 超级简单:代码生成器

      代码:/Files/zhuqil/SqlClassFactory_src.zip

    介绍

         这个项目,通过给出数据源,在一个listbox中它将会列出数据源服务上的所有的数据库,旁边的listbox将会列出对应数据库中所有的数据表。然后能生成该表的实体类抽象层。产生的类名和数据表名一致。然后将生产的代码保存为.cs源代码文件。

    代码说明:

          看上面的图,你将发现这个解决方案包括了一个类库项目和一个测试的windowsform项目TestForm。TestForm包括了两个Form,TestMain.cs Input.cs。Input form 用来得到数据库服务器的数据源(通常是.)或者通过输入数据库服务器名,用户名,密码通过验证登陆。TestForm是受验证控制的,当验证通过时,它将会出现在屏幕中。否者应用程序将会自动退出。

              

     

       在sqlclassfactory 类库项目中有很多不同的类。这里所有的类都是静态的。出发点先看Constants类。这个类包含像连接字符串这类不经常变动的字符串。ConnStrArgs.cs 文件中包含一个名字为Args的静态类 ,这个类很关键。因为在其他数据库操作之前,它是必须先做。所有其他静态类从这一类获得服务器的信息。如下所示,必须先设置:

    SqlClassFactory.Args.Reset();
    SqlClassFactory.Args.Type 
    = SqlClassFactory.enmConnStrType.Trusted;
    SqlClassFactory.Args.DataSource 
    = dataSource;
    SqlClassFactory.Args.InitialCatalog 
    = "master";

      

         下一个类是Connections.cs 类。这个类有一个名字为_connection 的类型为SqlConnection的私有字段。它包含了一个静态的方法 GetConnection().。这个方法从Constants 得到带参数格式化的字符串,再从Args 类中得到参数值。构建一个新的connection 并返回。就像你看到得一样,每一次,这个方法将一次又一次的通过设置过的Args 调用一个新的connection 。

       Commands 类仅仅是一个SqlCommand 的宿主。  commands类的CommandTextConnection 属性在Adapters类中设置.这些属性在Adapters类中将像如下设置:

     

    Commands.ListDBCmd.CommandText = Constants.ListDBStr;
    Commands.ListDBCmd.Connection 
    = Connections.GetConnection();
    Adapters._serverDA 
    = new SqlDataAdapter(Commands.ListDBCmd);

       例如,这里设置ListDBCmd command和ServerDA属性是使用这个command一个新的SqlDataAdapter

    最后一个类是Generator。这个静态类包含一个BeginGeneration(string)的方法。这个方法像一个构造器传递一个字符串的参数给rawClassText 。我将使用的代码部分真正地解释它们。

    Class.txt

        Class.txt包含rawClassText的一个文件。rawClassText是用由指定的数据库来生成数据表代理类。Class.txt 中有一些特殊的字段<...>,这些字段将会被匹配的属性名或者类名来取代 。 

    代码
    public DataTable DoSelect(string SqlCommandText)
    {
        SqlCommand selectCommand 
    = new SqlCommand(SqlCommandText);
        selectCommand.Connection 
    = sqlConnection;
        sqlDA.SelectCommand 
    = selectCommand;
        DataTable retdt 
    = new DataTable();
        sqlDA.Fill(retdt);
        
    return retdt;
    }

         这里 你看到了"Class.txt"的DoSelect()方法。sqlDA是类的成员它在构造器中初始化。这是这个类中最简单的方法。通过填补数据集ret,然后返回ret。

    代码
    public bool DoInsert(string SqlCommandText, params object[] args)
    {
        SqlCommand insertCommand 
    = new SqlCommand(SqlCommandText);
        
    string argInCmd = null;
        Regex r 
    = new Regex(@"@(\S+)", RegexOptions.IgnoreCase);
        
    int i = 0;
        
    if (r.Matches(SqlCommandText).Count == args.Length)
        {
            
    foreach (object arg in args)
            {
                argInCmd 
    = r.Matches(SqlCommandText)[i].ToString();
                argInCmd 
    = argInCmd.Trim().TrimEnd(new char[] {')'','});
                insertCommand.Parameters.AddWithValue(argInCmd, arg);
                i
    ++;
            }
        }
        
    else
            
    return false;
        insertCommand.Connection 
    = sqlConnection;
        sqlConnection.Open();
        
    bool ret = insertCommand.ExecuteNonQuery() > 0;
        sqlConnection.Close();
        
    return ret;
    }

       这里你看到"Class.txt"的DoInsert()方法。这种方法比较复杂。它这样被使用:DoInsert("Insert into Employees (firstname, lastname) values (@fname, @lname)", "Ozgur", "Sonmez"); 这是所有项目的最聪明的方法。这需要params类型的参数args。args包含了所有添加到sqlcommand的参数。在上面的例子中字符串argInCmd中'@fname' 是第一参数,@lname是第二个参数。 argInCmd将用来进行轮转参数匹配。

       new Regex(@"@(\S+)", RegexOptions.IgnoreCase); 是用来匹配'@matched_parameter'这是后采取<r.Matches(SqlCommandText)[i].ToString();>对于有些原因我无法找到使C#完全的匹配,因此会得到 '@lname)' 或者 '@fname,' 所有我需要做一些裁剪的工作。完全匹配的字符将会保存在argInCmd中,通过Parameter.AddWithValue()方法将它添加到sqlcommand的参数中,然后打开连接connection,执行ExecuteNonQuery。

    使用代码:

       这个代码包含了一个类库项目和一个test form的windowsform项目。为简洁起见,我通过使用SqlClassFactory dll来将两个分开的listbox 控件来显示数据库和关系数据表。类库项目生成SqlClassFactory.dll ,主入口是TestForm.exe。你能在任何地方使用这个SqlClassFactory.dll类库,都能得到两份名单。但这不是SqlClassLibrary仅有的工作。它也包含了通用的Generator类。这个类里面包含了public static void BeginGeneration(string rawText)。这个方法从 Class.txt中得到rawText字符串,用适当的名字替换所有的<...>。这里给出Class.txt的部分作为例子:

    namespace <database_name> 
    public class <table_name> 
    <column_name> 
    SqlDataAdapter sqlDA 
    = null
    SqlConnection sqlConnection 
    = null;

    下面是TestForm应用程序的核心:

    代码
        SqlClassFactory.Generator.BeginGeneration(rtxtClass.Text);
        SqlClassFactory.Generator.AddTableDBName(tableName, dbName);
        
    foreach (DataRow row in dtColumns.Rows)
        {
            SqlClassFactory.Generator.AddField
                (row[
    "DATA_TYPE"].ToString(), row["COLUMN_NAME"].ToString());
            
        }
        SqlClassFactory.Generator.EndGeneration();
        rtxtClass.Text 
    = SqlClassFactory.Generator.RawClassText;

        这里静态方法BeginGenerator()从richtextbox rtxtClass中获取文本数据,它在SqlClassFactory.Generator类的内部。然后在rtxtClass.Text中Generator.AddTableDBName(..)用适合的字符替换"<database_name>" 和"<table_name>" 。接着一个foreach 循环中每次都执行Generator中的静态方法AddField(),这用来属性名称,原类的字符串来自Class.txt。这个方法用属性名取代"<column_name>" 。也就是在给定的数据库表的列名。你可以从上面给出的参数:row["DATA_TYPE"].ToString(),

     row["COLUMN_NAME"].ToString()。

       这个功能值得关注。在这个功能有行的关键代码如下:

    代码
    string fieldText =
                    String.Format(
    "public {0} {1}", propertyType, propertyName) 
                    
    + " { get; set; }\n\t\t\t<column_name>";
    RawClassText 
    = RawClassText.Replace("<column_name>", fieldText);

        这里,每次调用AddField(),fieldtext 被设置成类似"public int productId { get; set; }"的字符串,首先取代属性的类型,然后取代属性的名字。接着设置为下次调用AddField()时使用的column_name ,首先为的属性名增加一新行,然后增加一行"<column_name>" 。

    SqlClassFactory.Generator.EndGeneration();

        这行代码使得String.Empty替换"<column_name>",清除多余的部分。

    rtxtClass.Text = SqlClassFactory.Generator.RawClassText;

     希望这篇文章对想写自己的代码生成器的朋友有所帮助(红色译者加)

    原文:http://www.codeproject.com/KB/database/SqlClassFactoryLibrary.aspx



    (全文完)


    以下为广告部分

    您部署的HTTPS网站安全吗?

    如果您想看下您的网站HTTPS部署的是否安全,花1分钟时间来 myssl.com 检测以下吧。让您的HTTPS网站变得更安全!

    SSL检测评估

    快速了解HTTPS网站安全情况。

    安全评级(A+、A、A-...)、行业合规检测、证书信息查看、证书链信息以及补完、服务器套件信息、证书兼容性检测等。

    SSL证书工具

    安装部署SSL证书变得更方便。

    SSL证书内容查看、SSL证书格式转换、CSR在线生成、SSL私钥加解密、CAA检测等。

    SSL漏洞检测

    让服务器远离SSL证书漏洞侵扰

    TLS ROBOT漏洞检测、心血漏洞检测、FREAK Attack漏洞检测、SSL Poodle漏洞检测、CCS注入漏洞检测。

  • 相关阅读:
    ArrayList removeRange方法分析
    LinkedHashMap源码分析(基于JDK1.6)
    LinkedList原码分析(基于JDK1.6)
    TreeMap源码分析——深入分析(基于JDK1.6)
    51NOD 2072 装箱问题 背包问题 01 背包 DP 动态规划
    51 NOD 1049 最大子段和 动态规划 模板 板子 DP
    51NOD 1006 最长公共子序列 Lcs 动态规划 DP 模板题 板子
    8月20日 训练日记
    CodeForces
    CodeForces
  • 原文地址:https://www.cnblogs.com/zhuqil/p/1626796.html
Copyright © 2011-2022 走看看