65.9K
CodeProject 正在变化。 阅读更多。
Home

数据库表的自动类生成器

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.26/5 (28投票s)

2004年11月12日

CPOL

4分钟阅读

viewsIcon

156536

downloadIcon

7908

这将创建一个类集,生成一组 C# 类文件,这些文件映射到数据库表。它们的类名将与表名相同,它们将拥有一组与表属性相同的属性。

Sample Image - ModelCreator.jpg

引言

如今,应用程序开发过程已大大扩展。有足够多的流程支持快速应用程序开发 (RAD)。但我们都知道,对于一个项目,时间至关重要。没有一种方法能够很好地适应。在这种情况下,无论我们是否喜欢,我们都会采取一种临时的方法。您会更改大部分定义,并根据当前需求进行定义。我并不是要证明这是最好的方法,但当需要快速完成某件事而与时间赛跑时,我觉得临时的方法很合适。但如果在我们的应用程序开发生命周期中拥有一个自动化过程会更好,换句话说,编写一个子应用程序来自动开发我们应用程序的某个部分,以兼顾速度和效率是很好的。

本文旨在寻找一种快速自动生成数据库模型类集的方法,使用一个可以自动/动态生成代码的子应用程序。作为初步方法,我将创建一个应用程序,它生成一组映射到数据库表的 CS 文件。它们的类名将与表名相同,它们的属性将与表属性相同。

如图所示,该应用程序创建了映射数据库所有表的模型类。它为每个类的属性创建 get/set 方法以及用户定义的构造函数,以便我们可以使用用户定义的构造函数在创建类时传递属性(设置属性)。

背景

正如我之前解释过的,有时,我们会以定义好的、标准化的方式开发应用程序,这才是更好的方法。但仍然有很多情况,至少我有很多过去的经验表明,在完全或部分开发应用程序后更改了数据库。那么,当您更改数据库时,作为一个并行过程,您必须更改模型类(如果您遵循 MVC 架构),换句话说,就是处理数据库操作的类集。此应用程序的下一个版本将引入一种自动化方法来完全解决该问题。在那里,该应用程序将开发一组负责大部分数据库操作的类,例如添加、删除、更新以及选择字段和记录。作为初步方法,我将专注于开发一个可以生成映射到数据库表的 C# 类文件的应用程序。

要求

阅读/测试本文的用户需要对 C# Windows Forms 应用程序开发、MS SQL server 和存储过程有所了解。此外,他们还应在其计算机上安装 Visual Studio .NET IDE 和 MS SQL server 7 或更高版本。

注意:如果您计划使用位于网络计算机上的 SQL server,则需要在您的计算机上安装“SQL Server Enterprise Manager”,或者您需要与您的网络管理员沟通,以便他们为您创建一个测试数据库。

使用代码

为了测试此应用程序,您需要一个有效的数据库服务器 IP 地址、一个简单的数据库以及连接到数据库的管理员用户凭据。显然,您需要创建一个包含一组表的数据库。以我的情况为例,我的数据库服务器名为“PRD-01”。在该服务器上,我创建了一个名为“ManGoDB”的数据库,并使用超级用户“sa”登录我的数据库。

进入应用程序

该应用程序仍处于非常基础的阶段,它有一个名为“ModelCreator.cs”的主要类,负责所有关键操作。应用程序的入口点是“Connect and Create”按钮的点击事件。它将触发一个“CreateConnectionString()”方法,该方法基本上获取用户输入并动态创建连接字符串。

private void lbtnConnect_Click(object sender, System.EventArgs e)
{
  if (CreateConnectionString())
    CreateModelClassFiles(tcGetDataReader());
}

一旦该过程完成,应用程序将调用名为 tcGetDataReader() 的方法。

/// <summary>
/// Get the SqlDataReader object
/// SqlDataReader
/// </summary>
public SqlDataReader tcGetDataReader()
{
  SqlConnection connection = null;
  try
  {
    connection = GetConnection(SQL_CONN_STRING);
    if (connection == null)
      return null;
    SqlDataReader dr = SqlHelper.ExecuteReader(
             connection,
             CommandType.StoredProcedure,
             "getData");
    if (dr.HasRows)
      return dr;
    else
      return null;
  }
  catch(Exception ex)
  {
    MessageBox.Show(ex.Message);
    return null;
  }
}

从数据库获取表名、属性及其类型

本文中一个更重要的部分是“getData”存储过程。它在一个表中检索表名、它们的属性以及这些属性的数据类型。该存储过程的读取方式如下:

CREATE PROCEDURE getData AS 
 select table_name, column_name, data_type
  from information_schema.columns
  where table_name in
  (
   select table_name
   from Information_Schema.Tables
   where Table_Type='Base Table'
  ) order by table_name
GO

主方法,CreateModelClassFiles

/// <summary>
/// Create the Model class list iterating through the tables
/// </summary>
/// <param name="dr">Sql Data reader for the database schema</param>
private void CreateModelClassFiles(SqlDataReader dr)
{
  if (dr != null)
  {
    string lstrOldTableName = string.Empty;
    StreamWriter sw = null;
    System.Text.StringBuilder sb = null;
    System.Text.StringBuilder sbAttr = null;
    while(dr.Read())
    {
      string lstrTableName = dr.GetString(0);
      string lstrAttributeName = dr.GetString(1);
      string lstrAttributeType = GetSystemType(dr.GetString(2));
      if (lstrOldTableName != lstrTableName)
      {
        if (sw != null)
        {
          this.CreateClassBottom(sw, sb.ToString().TrimEnd(
                     new char[]{',', ' ', '\r', '\t', '\n'}),
                     sbAttr.ToString());
            sw.Close();
        }
        sb = new System.Text.StringBuilder(lstrTableName);
        sb.Append(".cs");
        FileInfo lobjFileInfo = new FileInfo(sb.ToString());
        sw = lobjFileInfo.CreateText();
        this.CreateClassTop(sw, lstrTableName);
        sb = new System.Text.StringBuilder("\r\n\t/// \r\n\t" + 
             "/// User defined Contructor\r\n\t/// \r\n\tpublic ");
        sbAttr = new System.Text.StringBuilder();
        sb.Append(lstrTableName);
        sb.Append("(");
      }
      else
      {
        this.CreateClassBody(sw, lstrAttributeType, lstrAttributeName);
        sb.AppendFormat("{0} {1}, \r\n\t\t", 
           new object[]{lstrAttributeType, lstrAttributeName});
        sbAttr.AppendFormat("\r\n\t\tthis._{0} = {0};", 
           new object[]{lstrAttributeName});
      }
      lstrOldTableName = lstrTableName;
      this.progressBarMain.Increment(1); 
    }
    MessageBox.Show("Done !!");
  }
}

一旦调用此方法,它将为您完成所有工作。

关注点

代码的某些部分仍然需要改进。同时,在我看来,当数据库模式以快速的速率变化时,可以极大地改进此应用程序,使其非常有效。

© . All rights reserved.