| 

.NET C# Java Javascript Exception

4
Hallo,

ich muss Daten aus einer SQL-Server DB exportieren.
Dabei sollten die Tabellen & Felder konfigurierbar sein, in etwa so wie beim Import/Export-Assistenten aus dem SQL Server Management Studio.

Dazu würde ich gerne die komplette Struktur einer MSSQL-Datenbank in ein Dataset einlesen.
Ich möchte also ein typisiertes Dataset zur Laufzeit anlegen, in dem Tabelle, Spalten, Fremdschlüssel, Primärschlüssel, Indexe usw. enthalten sind.

Ich hatte erwartet dass es dafür eine einfache Möglichkeit gibt, habe aber nix gefunden.
Hab ich was übersehen oder muss ich dazu über GetSchema gehen und die Struktur dann von Hand aufbauen?

SqlConnection conn = new SqlConnection(connectionString);
conn.Open();
var tables = conn.GetSchema("Tables");
var columns = conn.GetSchema("Columns");
var foreignKeys = conn.GetSchema("ForeignKeys");
var indexes = conn.GetSchema("Indexes");
// -> Erstelle DataSet aus den Schema-Informationen
21.08.2012
erh 86 1 3
2 Antworten
0
Dazu würde ich gerne die komplette Struktur einer MSSQL-Datenbank in ein Dataset einlesen.
Ich möchte also ein typisiertes Dataset zur Laufzeit anlegen, in dem Tabelle, Spalten, Fremdschlüssel, Primärschlüssel, Indexe usw. enthalten sind.

Wieso möchtest Du ein typisiertes DataSet zur Laufzeit erstellen? Wer soll damit arbeiten? Ein typisiertes DataSet wird normalerweise vom VS Designer generiert und ist dann eine Sammlung von Klassen (Tables, Rows, ... immer Ableitungen von DataTable, DataRow, etc.), die die Datenstruktur über Navigationsproperties bzw. typisierte Daten-Properties (Row) abbildet. So etwas zur Laufzeit zu erstellen macht in meinen Augen irgendwie wenig Sinn. Versteh ich irgendwas nicht richtig?

Ein untypisiertes Dataset hingegen bildet die Struktur generisch ab. Siehe MSDN für Details.

Da ich mir noch unsicher bin, was Du genau meinst, hier mal ein Versuch (bin mir nicht zu 100% sicher, ob das funktioniert, ist aber in 5 min ausprobiert):

  • Füge via VS Designer eine Connection auf Deine DB ein
  • Erzeuge mit dem Designer ein typisiertes DataSet. Wähle dazu einfach alle Elemente der DB aus, die darin enthalten sein sollen.
  • Schreib eine kleine ConsoleApp, die das DataSet erzeugt und dann mit Hilfe der DataSet.WriteXmlSchema() Methode als Xml speichert.
  • Erzeuge eine neue Instanz von DataSet (untypisiert) und lies das Schema mit ReadXmlSchema ein. Das kannst Du Dir auch sparen, wenn Du mit dem typisierten weiterarbeiten möchtest, je nachdem.

Falls das nicht das sein sollte, was Du suchst, musst Du mir nochmal irgendwie auf die Sprünge helfen, dann wage ich einen neuen Versuch.

EDIT :
Nach Deinem zweiten Post verstehe ich Dich besser. So wie Du es machst, ist es ja schon ganz gut. Ich würde aber nur das INFORMATION_SCHEMA abfragen und nicht die Systemtabellen.
Ansonsten könnte der OpenSource Database Schema Reader noch für Dich interessant sein.

Florian
27.08.2012
ffordermaier 8,4k 3 9
Danke für den Link zum "Database Schema Reader", schaue ich mir gerade an.

Die Systemtabellen verwende ich nicht, hab die zwar in meinem Beitrag erwähnt, allerdings nur als etwas das ich gerne vermeiden würde.
erh 27.08.2012
0
Hi Florian,

du hast recht, ich hab mich etwas unglücklich ausgedrückt.
Ich benötige keinen typisierten Dataset sondern die Struktur der DB in einem DataSet.
Einen zur Designzeit erzeugten typisierten Dataset kann ich gar nicht verwenden, da die Struktur der DB evtl. abweicht.

Wie gesagt, ich sollte einen konfigurierbaren Datenexport aus einer oder mehreren Tabellen einer SQL-Server DB schreiben.
Dazu benötige ich Informationen welche Tabellen/Felder existieren und wie die Primärschlüssel aussehen (evtl. noch Indexe/Fremdschlüsselbeziehungen).

Das Abfragen dieser Informationen über die SQL Server Systemtabellen (sysobjects, syscolumns, ...) ist aber recht mühselig. Da diese Informationen in einem zur Designzeit erzeugten typisierten Dataset alle enthalten sind, dachte ich dass ich so einen typisierten Dataset zur Laufzeit mit ein paar Zeilen Code anlegen kann, haber aber nix gefunden.

Weiter unten ist mal mein bisheriger Code um die DB-Struktur in einen DataSet einzulesen.
Ist eigentlich auch recht simpel und es sind alle Infos drin die ich (bisher) benötige.
Infos zu Indexes/Fremdschlüssel fehlen noch, aber bei Bedarf kann ich diese Infos über SqlConnection.GetSchema bzw. Information Schema Views rausbekommen.

private DataSet ReadDatabaseToDataset(SqlConnection conn)
{
DataSet ds = new DataSet(conn.Database);

foreach (string tableName in SqlUtils.GetUserTables(conn))
{
using (var cmd = new SqlCommand("select * from " + tableName, conn))
{
using (var reader = cmd.ExecuteReader(CommandBehavior.SchemaOnly))
{
DataTable table = ds.Tables.Add(tableName);
table.Load(reader);
}
}
}

return ds;
}

private static class SqlUtils
{
public static List<string> GetUserTables(SqlConnection conn)
{
using (DataTable dtTables = conn.GetSchema("Tables"))
{
var tableNames = from DataRow row in dtTables.Rows
orderby row.Field<string>("TABLE_NAME")
select row.Field<string>("TABLE_NAME");

return tableNames.Where(s => s != "sysdiagrams" && s != "dtproperties").ToList();
}
}
}
27.08.2012
erh 86 1 3
Ok, jetzt verstehe ich Dich besser. Hab meiner Antowrt noch ein kleines Update hinzugefügt.
ffordermaier 27.08.2012

Stelle deine .net-Frage jetzt!
TOP TECHNOLOGIES CONSULTING GmbH