代码生成器开发笔记(2)-数据库架构

news/2024/7/4 9:04:21

代码生成器开发笔记(2)-数据库架构

程序 2009-06-13 01:30:01 阅读55 评论0   字号: 订阅

  要完成代码生成器,第一个要解决的是完全解析数据库架构。

  对SQL Server当然没什么问题,早在ADO时代就可以通过查询sysobjects之类的系统表来完全得到所需的架构信息,不过这种方式较为烦琐,而且对其它数据库也不一定适用。要支持的四种数据库中,SQL Server是最熟悉的,也是绝对保证不会有问题的,对Access数据库,虽然不太清楚它的架构信息是如何保存的,但ADO时代就可以使用ADOX来获得,ADO.NET当然也应该提供类似的方法,所以也不必担心。而Oracle和MySql只是用过,对其架构就完全不了解了,不过这两个数据库系统当然也会提供让开发者能获得架构信息的方式,所以倒也不用担心不能获得架构信息。

  这里考虑的是不能用查询系统表的方式来获得架构信息,其它三种不同数据库,即使全部提供了类似SQL Server的系统表,但各自存储的方式不同,必然导致代码无法重用,而给四个数据库系统写不同的提取架构信息的方法,那将是一件非常可怕的事情,这绝不是我的第一选择,除非ADO.NET没有提供更好的方法。

  以前从没有仔细研究过ADO.NET,对新技术,我一向是够用就行,从开发角度来讲,只要知道连接、命令等几个对象足矣,这次不同了,必须得深入一下……

  没必要去买书,也没必要去网上漫无目的地搜索,最好的参考当然是MSDN。

  首先从最熟悉的SqlConnection类入手,在MSDN中找到该类的所有方法,逐个研究,很快发现一个方法:GetSchema()——返回数据源的架构信息。而且它是SqlConnection的基类DbConnection中的虚方法(抽象方法?没注意),这就意味着OleDbConnection和OracleConnection也同样可以使用这个方法,至于MySql,虽然还没用C#写过MySql应用程序,但是不必担心,它的C#支持类库,用脚想也知道一定是继承同一个基类。所以只要搞清楚了一个数据库中的GetSchema用法,其它数据库也就迎仞而解了。更重要的是,这是完全面向对象的,代码可以重用。

  通过GetSchema,在MSDN中找到了“检索数据库架构信息”一章,终于搞清了在ADO.NET中获得数据库架构信息的方法,而且正如我所想,这是完全面向对象的,只需用简单工厂模式创建不同的Connection对象即可完全实现代码重用,大大简化了代码量。

  ADO.NET 2.0 允许提供程序编写者公开 5 种不同类型的元数据。这些主要的元数据 — “元数据集合”或“类别” — 在 System.Data.Common.DbMetaDataCollectionNames 类中被枚举出来。 

MetaDataCollections — 可用元数据集合的列表。 
 
Restrictions — 对于每个元数据集合,存在一批可以用于限制被请求的架构信息范围的限定符。 
 
DataSourceInformation — 关于数据提供程序引用的数据库实例的信息。 
 
DataTypes — 一组关于数据库支持的每个数据类型的信息。 
 
ReservedWords — 适用于该种数据库查询语言的保留字。通常“查询语言”等同于一种 SQL 的方言。 

Restrictions
Restrictions 可以用来限制返回元数据的数量。实际上也就是对返回的架构信息进行过滤。使用时,根据不同的架构来设置Restrictions的值,例如在查询数据库中所有用户表时,可以使用以下代码:

                using (DbConnection conn = DbFactory.CreateConnection(type, connectionString))
                {
                    conn.Open();
                    string[] restrictions = new string[4];
                    restrictions[3] = "BASE TABLE";    //SQL Server中用户表的类型名称
                    DataTable dt = conn.GetSchema("Tables",restrictions );  //查询数据提供程序的表视图
                    foreach (DataRow row in dt.Rows)
                    {
                        Table table = new Table(row["TABLE_NAME"].ToString());
                        tables.Add(table);  //添加到自定义的表集合中
                    }

  conn.GetSchema("Tables")的返回值是一个包含4个字段的结果集,其中第4个字段是表类型,将数据中的第4个元素的值设为"BASE TABLE",其含义等同于SQL语句中的WHERE table_type='BASE TABLE'。
  对无需过滤的字段,需要将restrictions数组中的相应元素设为null而不是空字符串(Empty),设置为空字符串的同义SQL语句为WHERE 字段名=''。

  Tables是架构集名称,具体解释可参见MSDN帮助,类似的架构名还有Columns、Views等,通过GetSchema(架构集名称,Restrictions)可以获得数据库架构的完整信息。

  然而架构集合是ADO.NET预定义好的,我们只能获得它定义好的架构信息,这些预定义的架构集合中并没有包含所有我们想要的东西,例如主键字段、主外键表等,要想获得这些信息,我们还得想办法。

  MSDN上的一篇文章谈到了这个问题。http://msdn.microsoft.com/zh-cn/library/ms379543(VS.80).aspx

  也就是说,我们可以通过自定义元数据的方式来获得我们想要的数据库架构信息。通过在配置文件中加入相应说明来告诉ADO.NET。

<?xml version="1.0" encoding="utf-8" ?> 
      <configuration> 
      <system.data.sqlclient> 
      <settings> 
      <add name="MetaDataXml" value="SQLBrokerAware.xml">
      </add> 
      </settings> 
      </system.data.sqlclient> 
      </configuration> 

例如这样一个配置文件,告诉ADO.NET,当使用SQL Server数据提供程序查询架构信息时,使用SQLBrokerAware.xml文件中的定义来进行查询。这份文件必须放在.NET框架安装目录下的CONFIG目录中。通常,.NET框架的典型安装目录是Windows/Microsoft.net/Frameword/版本号。可以通过检查注册表HKEY_LOCAL_MACHINE/Software/Micorsoft/.NetFrameword/InstallRoot的值来确定安装目录,并且在程序中使用Environment.Version检查.NET框架的版本号,最终确定元数据描述文件应该放在哪里。

  有了这个文件,我们可以对任意一个支持ADO.NET的数据库查询我们想知道的架构信息。以下是关键部分的描述:

  <MetaDataCollections>
    <CollectionName>Tables</CollectionName>
    <NumberOfRestrictions>4</NumberOfRestrictions>
    <NumberOfIdentifierParts>3</NumberOfIdentifierParts>
    <PopulationMechanism>SQLCommand</PopulationMechanism>
    <PopulationString>select table_catalog, table_schema, table_name, table_type from information_schema.tables where table_catalog = {0} and table_schema = {1} and table_name = {2} and table_type = {3}</PopulationString>
  </MetaDataCollections>

这里描述了如何获得数据库中表的信息。

MetaDataCollections——元数据集合,每一个集合都必须放在这个标签内

CollectionName——集合名称,GetSchema方法的第一个参数

NumberOfRestrictions——允许的限制数,决定了代码中定义的restrictions数组的大小

NumberOfIdentifierParts——必须的限制数,此值不为零时,restrictions数组不能为null的元素的个数。

PopulationMechanism——向数据库发出命令的DbCommand实例。根据不同的数据库,这个值应该是                                       SqlCommand、OracleCommand等。

PopulationString——用来替换“基查询”的SQL语句。显然修改这个值,我们可以得到我们想要的任何信息。

  关于元数据描述文件更多定义,可以使用托管代码反汇编工具ILDasm反编译system.data.sqlclient.dll文件,查看里面的System.Data.SqlClient.SqlMetaData.xml文件,这个文件就是ADO.NET预定义好的元数据描述文件。

  具体做法是:进入VS命令环境,切换到.NET框架安装目录下,运行以下命令:ildasm System.Data.dll /out:system.data/dummy.il,将会在当前目录下生成system.data目录,并将反编译后生成的文件放在里面。这里的system.data是我自定义的目录名,你也可以换成其它名称,目录不需要预先存在,ildasm会自动创建。


http://www.niftyadmin.cn/n/1895015.html

相关文章

mysql on linux 安装_MySQL on Linux手动安装方法

MySQL on Linux手动安装方法发布时间:2007-06-05 11:44:45来源:红联作者:TecCTO1. 下载"mysql-standard-5.0.27-Linux-i686-icc-glibc23.tar.gz"&#xff0c;推荐ICC版本&#xff0c;据称比GCC性能提高10-20%2. 复制到/usr/local/&#xff0c;解压&#xff1a;tar zx…

MongoDB最新最佳连接工具:Robo 3T

MongoDB连接工具 像使用Mysql&#xff0c;喜欢用Navicat连接工具一样。 在使用MongoDB数据库的时候&#xff0c;同样可以使用Robo 3T图形化工具。 一、下载Robo 3T Robo 3T官网 Studio 3T&#xff1a;专业人士使用的&#xff0c;需要付费。 Robo 3T&#xff1a;虽然免费&…

mysql audit_mysql5.7添加日志审计插件audit-plugin

来自McAfee的MySQL插件&#xff0c;为MySQL提供审计功能&#xff0c;重点是安全性和审计要求。该插件可以用作独立的审核解决方案&#xff0c;也可以配置为将数据提供给外部监视工具。插件下载地址&#xff1a;首先查看mysql的插件保存目录&#xff1a;mysql> show global v…

代码生成器开发笔记(3)-界面设计

代码生成器开发笔记(3)&#xff0d;界面设计 程序 2009-06-13 13:48:34 阅读73 评论0 字号&#xff1a;大中小 订阅 解决了数据架构问题&#xff0c;开始正式动手写代码。 第一个问题当然是界面设计了。准备做成VS2005风格&#xff0c;也就是多文档、支持窗体停靠&#xf…

拓扑排序c语言代码_折半插入排序算法(C语言代码实现)

上一节介绍了直接插入排序算法的理论实现和具体的代码实现&#xff0c;如果你善于思考就会发现该算法在查找插入位置时&#xff0c;采用的是顺序查找的方式&#xff0c;而在查找表中数据本身有序的前提下&#xff0c;可以使用折半查找来代替顺序查找&#xff0c;这种排序的算法…

分布式数据库操作笔记

/*映射和删除远程服务器连接 */exec sp_addlinkedserver serverdemo, srvproduct,datasrc192.168.2.93,providerSQLOLEDB /* 不能再事务中执行存储过程*/ exec sp_dropserver demo select * from sys.servers /*查询此服务器中所有服务器映射记录 */ /*映射和删除远程服务器…

yii2安装mysql_linux 安装mysql5.6

Linux:Centos1.先查看系统上有没有安装了旧版本的MySQL &#xff0c;用下面的命令&#xff1a;rpm -qa | grep mysql如果有&#xff0c;用以下命令卸载rpm -e --nodeps 上步显示mysql名称安装编译mysql 需要的依赖包yum install libevent* libtool* autoconf* libstd* ncurse* …

分布式数据库概述

http://fineboy.cnblogs.com/archive/2005/08/03/206395.html