Как получить XSD для базы MSSQL

acol
Дата: 14.02.2005 17:53:21
Столкнулся с проблемой.
Имеется DataSet, повторяющий схему базы данных в MSSQL. Когда меняю структуру базы, приходится праллельно вность изменения в DataSet.
Не подскажите, может есть какая утилита, которая строила бы XSD по базе данных?
кузя
Дата: 14.02.2005 22:08:20
простейший способ - есть в студии:
добавляешь к пректу XML Schema (Project->Add New Item->XSD Schema) или DataSet XSD. открываешь окно Server Explorer, выбираешь(добавляешь в него) сервер сети с БД MSSQL.
из SQL Server выбираешь БД и перетягиваешь узел дерева Tables (или выделяешь те таблицы, на которые нужно получить схему) на XSD документ.
PS
некоторые вещи затем приходится доделывать руками
кузя
Дата: 15.02.2005 04:11:58
кстати, вот пример небольшого генератора XSD для MS SQL сервера, работающий через OleDb
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]);
      }
    }
    /**************************************************************************************************************/
  }
}
acol
Дата: 15.02.2005 11:45:14
Большое спасибо.
То, что нужно!!!!!