using System;
using System.Data;
using System.Data.OleDb;
using System.Collections;
namespace CreateXSD
{
class CreateXSD
{
[STAThread]
static void Main(string[] args)
{
GenerateXSD("Provider=SQLOLEDB.1;Integrated Security=SSPI;Initial Catalog=Northwind;Data Source=STORAGE", @"C:\Temp\Schema.xsd", true);
}
/**************************************************************************************************************/
/// <summary>
/// генерация схемы БД и запись ее в файл
/// </summary>
public static void GenerateXSD(string cs, string file, bool createConstraints)
{ OleDbConnection cn=new OleDbConnection(cs);
DataSet ds=new DataSet(cn.Database);
try
{
cn.Open();
// добавить все TABLE
AddTables(cn, ds, null, "TABLE");
// добавить все VIEW
AddTables(cn, ds, null, "VIEW");
// добавить RELATIONS для выбранных таблиц
AddRealations(cn, ds, createConstraints);
// запись схемы в файл
ds.WriteXmlSchema(file);
}
catch(Exception ex)
{ Console.WriteLine("{0}", ex.ToString());
Console.ReadLine();
}
finally
{
if(cn.State!=ConnectionState.Closed) cn.Close();
}
Console.WriteLine("Total: {0} tables/views, {1} relations", ds.Tables.Count, ds.Relations.Count);
Console.WriteLine("Press [Enter] for exit");
Console.ReadLine();
}
/**************************************************************************************************************/
/// <summary>
/// добавление схем таблиц (TABLE) и представлений (VIEW)
/// </summary>
public static void AddTables(OleDbConnection cn, DataSet ds, string name, string filter)
{
DataTable ts=cn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[]{null, null, name, filter});
for(int k=0; k<ts.Rows.Count; k++) // таблицы
{ string tbln=Convert.ToString(ts.Rows[k]["TABLE_NAME"]);
OleDbDataAdapter ad=new OleDbDataAdapter("SELECT * FROM ["+tbln+"]", cn);
ad.FillSchema(ds, SchemaType.Mapped, tbln);
}
}
/**************************************************************************************************************/
/// <summary>
/// добавление DataRelation для всех таблиц в DataSet
/// </summary>
public static void AddRealations(OleDbConnection cn, DataSet ds, bool createConstraints)
{
for(int k=0; k<ds.Tables.Count; k++)
{
string ft=ds.Tables[k].TableName; // имя таблицы, для которой строим FK
DataTable tr=cn.GetOleDbSchemaTable(OleDbSchemaGuid.Foreign_Keys, new object[]{null, null, null, null, null, ft});
DataView dt=new DataView(tr);
dt.Sort="PK_TABLE_NAME, ORDINAL"; // отсортируем DataView по имени PK таблицы и порядковому номеру колонок в ключе
string pt=string.Empty; // имя PK таблицы
string rn=string.Empty; // имя Relation'а
ArrayList ptc=new ArrayList(); // имена полей ключа в PK таблице
ArrayList ftc=new ArrayList(); // имена полей ключа в FK таблице
for(int m=0; m<dt.Count; m++)
{
string tb=Convert.ToString(dt[m]["PK_TABLE_NAME"]);
string nm=Convert.ToString(dt[m]["FK_NAME"]);
if(!ds.Tables.Contains(tb)) continue; // таблицы нет - нехера и смотреть...
if((string.Compare(tb, pt, true)!=0 || string.Compare(rn, nm, true)!=0) && ptc.Count>0)
{ // построить Realation для предыдущей PK таблицы
AddRelation(ds, rn, pt, ptc, ft, ftc, createConstraints);
ptc.Clear();
ftc.Clear();
}
pt=tb; rn=nm;
ptc.Add(dt[m]["PK_COLUMN_NAME"]);
ftc.Add(dt[m]["FK_COLUMN_NAME"]);
}
if(ptc.Count>0)
{ // построить Relation для последней PK таблицы
AddRelation(ds, rn, pt, ptc, ft, ftc, createConstraints);
}
}
}
/**************************************************************************************************************/
/// <summary>
/// добавление foreign key как DataRelation
/// </summary>
public static void AddRelation(DataSet ds, string relationName, string pt, ArrayList ptf, string ft, ArrayList ftf, bool createConstraints)
{ DataColumn[] ptc=new DataColumn[ptf.Count];
DataColumn[] ftc=new DataColumn[ftf.Count];
for(int k=0; k<ptf.Count; k++)
{ ptc[k]=ds.Tables[pt].Columns[(string)ptf[k]];
ftc[k]=ds.Tables[ft].Columns[(string)ftf[k]];
}
try
{ // вот здесь бывают всякие блядские штучки для различных типов БД
ds.Relations.Add((relationName==string.Empty) ? null : relationName, ptc, ftc, createConstraints);
}
catch(Exception ex)
{
Console.WriteLine("\r\n*** {0}", ex.Message);
Console.WriteLine("\r\n*** PK table: {0}", pt);
for(int k=0; k<ptc.Length; k++) Console.WriteLine("\t{0}", ptc[k]);
Console.WriteLine("\r\n*** FK table: {0}", ft);
for(int k=0; k<ftc.Length; k++) Console.WriteLine("\t{0}", ftc[k]);
}
}
/**************************************************************************************************************/
}
} |