SQL Server 数据库的映射表、表间关系和列信息






3.91/5 (8投票s)
展示了一种映射 SQL Server 2000/2005 数据库的表、表间关系和列信息的方法;同时使用 C# (TableReader) 在运行时生成 INSERT、UPDATE、DELETE 和 SELECT SQL 语句。

引言
在运行时映射数据库表、列和关系的需求,基本要素是了解表的四个属性。
- 检查表是否存在
- 获取代表数据库中表的对象的集合
- 了解每个表哪些列是标识列/主键、是否可空、数据类型、默认值和大小(取决于数据类型)
- 两个或多个表之间的关系
本文解释了 Class Library TableReader 如何读取数据库并返回其数据映射。
在第一个版本中,只能读取表、列和关系。在第二个版本中,实现了一些接口和方法,以提高可用性和与其他类的集成。
它是如何读取表的
这个类库使用 SQL 语句读取表的所有列,使用一些本地存储过程来检查表是否存在于数据库中,并读取所有表以及表之间的所有关系。
- 检查表是否在数据库中存在
--This stored procedure "sp_tables" is native in the SQL Server 
sp_tables @table_type = "'TABLE'", @table_name='The name of the Table to be checked'
要了解更多关于“sp_tables”的信息,请访问 MSDN 链接:http://msdn2.microsoft.com/en-us/library/ms186250.aspx。
--This Sql Satatement returns all the columns of a certain table.
SELECT c.COLUMN_NAME, c.IS_NULLABLE, c.DATA_TYPE, c.CHARACTER_MAXIMUM_LENGTH, 
tc.CONSTRAINT_TYPE, COLUMNPROPERTY(OBJECT_ID(c.TABLE_NAME), 
      c.COLUMN_NAME, 'IsIdentity') AS IS_AUTOINCREMENT, COLUMN_DEFAULT 
FROM INFORMATION_SCHEMA.COLUMNS c 
LEFT JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu on 
     c.COLUMN_NAME = kcu.COLUMN_NAME AND c.TABLE_NAME = kcu.TABLE_NAME 
LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS 
     tc on kcu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME 
WHERE c.TABLE_NAME = 'The name of the Table to be read' BY c.ORDINAL_POSITION
--The same stored procedure used to check if a table exists,
--if the parameter "@table_name" is not used,
--it returns all the tables in the database
sp_tables @table_type = "'TABLE'"
sp_fkeys @pktable_name = 'Primary Table', @fktable_name = 'Foreign Table'
要了解更多关于“sp_fkeys”的信息,请访问 MSDN 链接:http://msdn2.microsoft.com/en-us/library/aa933402(SQL.80).aspx。
改进
类现在是可序列化的
fTableReader 对象可以被序列化,添加到 ViewState 等。
添加了基于列值对获取表 SELECT、INSERT、UPDATE 和 DELETE SQL 子句的方法。
fColumnValue 类用于将列与字符串值关联。
将 List<fColumn> 发送给这些方法,以过滤子句或属性值。
//Creates an List of fColumnValues
List<fcolumnvalue> lstFcv = new List<fcolumnvalue>();
//Add a fColumnValue for Column 'myColumnName1' that
//is at Table 'myTableName' and with the value 'Value for Column 1'
lstFcv.Add(new fColumnValue(MyfTableReader["myTableName"]["myColumnName1"], 
           "Value for Column 1"));
//Add a fColumnValue for Column 'myColumnName' that is at Table 
//'myTableName' and with the value 'Value for Column 2'
lstFcv.Add(new fColumnValue(MyfTableReader["myTableName"]["myColumnName2"], 
           "Value for Column 2"));
//Add a fColumnValue for Column 'myColumnName3' 
//that is at Table 'myTableName' and with Empty value
lstFcv.Add(new fColumnValue(MyfTableReader["myTableName"]["myColumnName3"]));
//Add a fColumnValue for Column 'myColumnName10' 
//that is at Table 'myTableName2' and with Empty value
lstFcv.Add(new fColumnValue(MyfTableReader["myTableName2"]["myColumnName10"]));
//Get the SELECT Clause for Table 'myTableName' Filtering with all Column
//Values of List 'lstFcv' related with Columns that belongs to Table 'myTableName'
string strSelect = "SELECT: " + 
   MyfTableReader["myTableName"].GetStringSelect(lstFcv);
//Get the UPDATE Clause for Table 'myTableName' with all Column Values 
//of List 'lstFcv' related with Columns that belongs to Table 'myTableName'
//IT Automatically speare the Primary Keys and update all Columns 
//that are not Primary Keys and Put The Primary Key Colmns in the WHERE Clause
string strUpdate = "UPDATE: " + 
       MyfTableReader["myTableName"].GetStringUpdate(lstFcv);
//Get the DELETE Clause for Table 'myTableName' withhe WHERE Clause 
//with all Column Values of List 'lstFcv' related with 
//Columns that belongs to Table 'myTableName'
//The flag inicates whether the Method should 
//put only Primary Keys in the Where Clause
string strDelete = "DELETE: " + 
  MyfTableReader["myTableName"].GetStringDelete(lstFcv, true);
//Get the INSERT Clause for Table 'myTableName' with all Column Values 
//of List 'lstFcv' related with Columns that belongs to Table 'myTableName'
//The Flag indicates whether the method should insert Identity Columns
string strInsert = "INSERT: " + 
   MyfTableReader["myTableName"].GetStringInsert(lstFcv, false);
向 fTable 和 fColumn 添加了 IComparable<T> 接口,以便它们可以分别按表名和列名排序。
为了按表名或列名对表或列进行字母排序,而无需使用带有表或列名列表的委托,因此实现了 IComparable<T> 接口,以便可以直接使用 Sort() 方法进行排序。
// Order the Tables in 'MyfTableReader' alphabetically
MyfTableReader.Tables.Sort();
// Order the Column in 'MyfTable' alphabetically
MyfTable.TableColumns.Sort();
向 fTableReader 和 fColumn 添加了 IList<T> 接口,以便它们可以作为 DataSource 使用。
为了方便地填充 DropDownList、RadioButtonList 等,实现了 IList<T> 接口。
//The DropDownList 'ddlMyDropDownListTables' DataSorce 
//is related to the fTableReader 'MyTableReader'
ddlMyDropDownListTables.DataSource = MyTableReader;
//Binds the DropDownList 'ddlMyDropDownListTables' 
//with all tables of the fTableReader 'MyTableReader' 
ddlMyDropDownListTables.DataBind();
//The DropDownList 'ddlMyDropDownListColumns' DataSorce is related 
//to the Table 'MyTable' in the fTableReader 'MyTableReader'
ddlMyDropDownListColumns = MyTableReader["MyTable"];
//Binds the DropDownList 'ddlMyDropDownListColumns' with all Columns 
//of the Table 'MyTable' in the fTableReader 'MyTableReader'
ddlMyDropDownListColumns.DataBind();
Using the Code
要使用 TableReader,您的项目必须是 .NET 2.0,并且需要引用项目源或 DLL。
此项目仅兼容 SQL Server 2000/2005。
使用泛型获取对象非常简单。下面是如何使用 TableReader 读取数据库及其表的示例代码。
第二个版本需要更少的代码来获取对象及其属性。下面是 TableReader 用法的一个示例。
//Create a new Instance of the TableReader, tr
fTableReader tr = new TableReader("server=Your SQL Server;Integrated " + 
                  "Security=false;User Id=User Name;Password=Your Password;" + 
                  "database=Your DataBase;Pooling=false;");
//Create a fTable Object
fTable newfTable1 = new fTable();
//Check if a Table Exists in the database
if (tr.CheckTableExistance("myTable"))
    newfTable1 = tr.AddTable("myTable");
//Add all tables of the database to the object tr
tr.AddAllTables();
//Get a table object by the Table Name
fTable newfTable2 = tr["myTable"];
//The Same as 'fTable newfTable2 = CommonMethod.GetTableByName(tr.Tables, "myTable");'
//Get all the relations of newfTable1 ("myTable") when it is a Foreign Table
List<ftablerelation> lstTableRelation = newfTable1.ForeignTablesRelation;
//The same as 'List<ftablerelation> lstTableRelation = 
//   tr.GetTableRelation(newfTable1, fTableReader.enfTableRelationType.ForeignTable);'
//Get a List<fcolumn> of All the Columns
//of newfTable1 ("myTable") that are Primary Keys
List<fcolumn> lstFcolumn = newfTable1.PrimaryKeys;
//The Same as 'List<fcolumn> lstFcolumn = 
//   CommonMethod.GetTableKeys(newfTable1, CommonMethod.enfTableKeyType.PrimaryKey);'
关注点
要了解更多信息,请访问 MSDN 链接:
- 泛型:http://msdn2.microsoft.com/en-us/library/ms379564(vs.80).aspx
- List泛型类:http://msdn2.microsoft.com/en-us/library/6sh2ey19.aspx
- IComparable泛型接口:http://msdn2.microsoft.com/en-us/library/4d7sx9hd.aspx
- IList泛型接口:http://msdn2.microsoft.com/en-us/library/5y536ey6.aspx
历史
v2.0 (2007/10/18)
- 添加了基于列值对获取表 SELECT、INSERT、UPDATE 和 DELETE SQL 子句的方法。
- 向 fTable和fColumn添加了IComparable<T>接口,以便它们可以分别按表名和列名排序。
- 向 fTableReader和fColumn添加了IList<T>接口,以便它可以作为 DataSource 使用。
- 类现在是 Serializable(可序列化的)。
- 向类添加了新的属性和方法。
- 错误修复。
v1.0 (2007/10/08)
- 首次发布。


