超級簡單:代碼產生器

來源:互聯網
上載者:User
  代碼:/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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.