So generieren Sie Datenbanktabellen aus C#-Klassen in Minuten automatisch

Das manuelle Erstellen von Datenbanktabellen kann eine mühsame Aufgabe sein, insbesondere wenn Sie mit einer erheblichen Anzahl von Klassen zu tun haben. Wenn Sie sich in einer Situation befinden, in der Sie Tabellen schnell generieren müssen, ohne lange SQL-Skripte schreiben zu müssen, sind Sie hier genau richtig. Dieser Blogbeitrag bietet eine Lösung, um Datenbanktabellen direkt aus Ihren C#-Klassen unter Verwendung von Reflection und etwas Programmiermagie automatisch zu generieren.

Das Problem

Stellen Sie sich vor, Sie haben mehrere C#-Klassen, und mit dem Wachstum Ihrer Anwendung müssen Sie entsprechende Datenbanktabellen für diese Klassen erstellen. Die manuelle Erstellung dieser Tabellen ist nicht nur mühsam, sondern auch fehleranfällig. Hier ist ein Beispiel für eine einfache C#-Klasse:

class Foo
{
    private string property1;
    public string Property1
    {
        get { return property1; }
        set { property1 = value; }
    }

    private int property2;
    public int Property2
    {
        get { return property2; }
        set { property2 = value; }
    }
}

Aus dieser Klasse würden Sie eine SQL-Anweisung wie folgt benötigen:

CREATE TABLE Foo
(
    Property1 VARCHAR(500),
    Property2 INT
)

Darüber hinaus kann der Umgang mit komplexen Typen innerhalb von Klassen, wie System.Management.ManagementObject, die Dinge weiter komplizieren, wie in einer modifizierten Version der Klasse Foo gezeigt.

Die Lösung

Schritt 1: Einrichten der Umgebung

Um zu beginnen, müssen Sie eine Konsolenanwendung in C# erstellen. Diese Anwendung wird Ihre Klassen inspizieren und SQL-Skripte dafür generieren. Hier ist eine vereinfachte Version, wie der Code funktioniert:

  1. Laden Sie die Assembly: Verwenden Sie Reflection, um die Assembly zu laden, die Ihre C#-Klassen enthält.
  2. Durchlaufen Sie die Typen: Schleifen Sie durch jede Klasse innerhalb der Assembly und sammeln Sie deren Eigenschaften.
  3. Erstellen Sie SQL-Skripte: Generieren Sie für jede Klasse ein CREATE TABLE SQL-Skript basierend auf ihren Eigenschaften und Typen.

Schritt 2: Codeimplementierung

Hier ist der Kern der Implementierung, den Sie an Ihre Bedürfnisse anpassen können.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace TableGenerator
{
    class Program
    {
        static void Main(string[] args)
        {
            List<TableClass> tables = new List<TableClass>();

            Assembly assembly = Assembly.LoadFile(args[0]);
            Type[] types = assembly.GetTypes();

            foreach (Type type in types)
            {
                TableClass tableClass = new TableClass(type);
                tables.Add(tableClass);
            }

            foreach (TableClass table in tables)
            {
                Console.WriteLine(table.CreateTableScript());
                Console.WriteLine();
            }
        }
    }

    public class TableClass
    {
        private List<KeyValuePair<string, Type>> fields = new List<KeyValuePair<string, Type>>();
        public string ClassName { get; set; }

        private Dictionary<Type, string> dataMapper = new Dictionary<Type, string>
        {
            { typeof(int), "BIGINT" },
            { typeof(string), "NVARCHAR(500)" },
            // Fügen Sie bei Bedarf weitere Zuordnungen hinzu
        };

        public TableClass(Type type)
        {
            ClassName = type.Name;
            foreach (PropertyInfo property in type.GetProperties())
            {
                fields.Add(new KeyValuePair<string, Type>(property.Name, property.PropertyType));
            }
        }

        public string CreateTableScript()
        {
            var script = new System.Text.StringBuilder();
            script.AppendLine($"CREATE TABLE {ClassName}");
            script.AppendLine("(");
            script.AppendLine("\t ID BIGINT,");

            for (int i = 0; i < fields.Count; i++)
            {
                var field = fields[i];
                script.Append($"\t {field.Key} {(dataMapper.ContainsKey(field.Value) ? dataMapper[field.Value] : "BIGINT")}");

                if (i != fields.Count - 1)
                {
                    script.Append(",");
                }
                script.AppendLine();
            }

            script.AppendLine(")");
            return script.ToString();
        }
    }
}

Schritt 3: Ausführen Ihres Codes

Sobald Sie die Assembly mit Ihren Datenklassen geladen haben, führen Sie einfach den Code aus. Er wird generierte SQL-Skripte ähnlich diesen produzieren:

CREATE TABLE FakeDataClass
(
    ID BIGINT,
    AnInt BIGINT,
    AString NVARCHAR(255)
)

CREATE TABLE FKClass
(
    ID BIGINT,
    AFKInt BIGINT
)

Weitere Überlegungen

  • Attribute zum Filtern: Erwägen Sie das Hinzufügen eines benutzerdefinierten Attributs, wie z.B. [SqlTable], zu Ihren Klassen, um sicherzustellen, dass nur festgelegte Klassen in Tabellen umgewandelt werden.
  • Verbesserungen: Der Code kann weiter optimiert und umstrukturiert werden. Zum Beispiel ist die Handhabung von Fremdschlüsselbeziehungen recht rudimentär und könnte von zusätzlicher Logik profitieren.

Diese Lösung bietet einen robusten Ausgangspunkt für die Automatisierung der Generierung von SQL-Tabellen basierend auf der Struktur von C#-Klassen. Viel Spaß beim Codieren!