超级简单:代码生成器

  代码:/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注入漏洞检测。

转载于:https://www.cnblogs.com/zhuqil/archive/2009/12/18/1626796.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值