MySQL是一个广泛使用的开源数据库管理系统,它对非商业用途是免费的。本文将介绍如何使用C#与MySQL数据库进行交互,并从中提取数据库架构。这对于开发人员在进行数据库活动时可能会遇到的问题,例如应用在数据库操作中崩溃,或者数据库不在开发/测试机器上的情况非常有用。需要的是能够捕获客户端数据库状态的工具,以便可以将其加载到测试机器中,从而重现客户遇到的情况,解决未发现的问题。
本文将介绍以下功能:
为了实现上述功能,需要以下工具:
首先,需要添加对MicrosoftODBC的引用。然后,使用using Microsoft.ODBC
语句来告诉程序想要使用MSODBC。简而言之,OdbcConnection
将用于打开连接,OdbcCommand
用于执行查询,OdbcDataReader
用于读取结果集。以下代码展示了每一步的操作。会注意到,它运行了MySQL特定的命令SHOW TABLES
来获取表的列表。然后,它根据特定表运行另一个查询,SHOW COLUMNS IN CURRENT_TABLE
。这就是代码所做的全部。
以下是C#代码示例:
public void PrepareSchema()
{
// 创建连接对象,通过设置DSN
OdbcConnection ocConnection = new OdbcConnection("DSN=" + strDSN);
// 创建第二个连接,以便在执行一个查询时进行其他查询
OdbcConnection ocConnection2 = new OdbcConnection("DSN=" + strDSN);
// 打开两个连接
ocConnection.Open();
ocConnection2.Open();
// 声明每个表和列的命令
OdbcCommand ocTableCommand;
OdbcCommand ocColumnCommand;
// 创建命令对象,这将执行SHOW TABLES查询。在MySQL中,它显示当前数据库中包含的所有表。
ocTableCommand = new OdbcCommand("SHOW TABLES", ocConnection);
// 声明表和列的读取器对象
OdbcDataReader odrTableReader;
OdbcDataReader odrColumnReader;
// 通过ExecuteReader()执行返回结果集的查询
// 如果要运行插入、更新、删除等查询,则会通过使用ExecuteNonQuery()来调用它们
odrTableReader = ocTableCommand.ExecuteReader();
// 在富文本框中放置创建数据库语句
rchtxtSchema.Text += "CREATE DATABASE " + ocConnection.Database + ";\r\n\r\n";
rchtxtSchema.Text += "USE DATABASE " + ocConnection.Database + ";\r\n\r\n";
string strTable = "";
string strColumnName = "";
string strColumnType = "";
string strColumnNull = "";
string strColumnPKey = "";
string strColumnDflt = "";
string strColumnExtr = "";
// 读取表集
while (odrTableReader.Read())
{
// 这里期望的行只有1列,包含表名。这就是为什么明确调用GetString()在0索引
strTable = odrTableReader.GetString(0);
rchtxtSchema.Text += "CREATE TABLE " + strTable + "\r\n(\r\n";
// 为每个表构建命令
ocColumnCommand = new OdbcCommand("SHOW COLUMNS IN " + strTable, ocConnection2);
// 运行查询
odrColumnReader = ocColumnCommand.ExecuteReader();
// 读取列集
while (odrColumnReader.Read())
{
// 这个查询返回列的名称、类型、是否可以为NULL、是否是主键、默认值以及额外信息,例如是否自动递增
strColumnName = odrColumnReader.GetString(0);
strColumnType = odrColumnReader.GetString(1);
strColumnNull = odrColumnReader.GetString(2);
strColumnPKey = odrColumnReader.GetString(3);
strColumnDflt = odrColumnReader.GetString(4);
strColumnExtr = odrColumnReader.GetString(5);
if (!strColumnNull.Equals("YES"))
strColumnNull = "NOT NULL ";
else
strColumnNull = "";
if (strColumnPKey.Equals("PRI"))
strColumnPKey = "PRIMARY KEY ";
// this.rchtxtSchema.Text += "\n";
rchtxtSchema.Text += "\n" + strColumnName + " " + strColumnType + strColumnPKey + strColumnNull + ",";
rchtxtSchema.Text += "\r\n";
}
rchtxtSchema.Text = this.rchtxtSchema.Text.Substring(0, this.rchtxtSchema.Text.Length - 3);
rchtxtSchema.Text += "\r\n);\r\n\r\n";
// 释放读取器对象
odrColumnReader.Close();
}
// 关闭读取器
odrTableReader.Close();
// 断开连接
ocConnection.Close();
ocConnection2.Close();
}
最初,在ODBC、ADODB和OLEDB之间来回尝试实现这个功能。根据MySQL的说法,使用OLEDB是不安全的。没有提到如何使用OLEDB执行简单的数据库任务。最后,决定使用ODBC会非常简单。可能已经注意到使用了特定DB提供商的内置命令(例如show tables
)。绝对愿意听取任何建议或与MySQL兼容的标准的工作示例。
保存架构:
查看架构: