Comment Auto-Gérer les Tables de Base de Données à partir des Classes C# en Quelques Minutes

Créer des tables de base de données manuellement peut être une tâche fastidieuse, surtout lorsqu’il s’agit d’un nombre important de classes. Si vous vous trouvez dans une situation où vous devez générer rapidement des tables sans avoir à écrire de longs scripts SQL, vous êtes au bon endroit. Cet article de blog propose une solution pour auto-gérer les tables de base de données directement à partir de vos classes C# en utilisant la réflexion et un peu de magie de codage.

Le Problème

Imaginez que vous avez plusieurs classes C#, et avec la croissance de votre application, vous devez créer des tables de base de données correspondantes pour ces classes. La création manuelle de ces tables est non seulement fatigante mais aussi sujette à des erreurs. Voici un exemple d’une simple classe C# :

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; }
    }
}

À partir de cette classe, vous auriez besoin d’une instruction SQL comme :

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

De plus, gérer des types complexes au sein des classes, comme System.Management.ManagementObject, peut compliquer davantage les choses, comme le montre une version modifiée de la classe Foo.

La Solution

Étape 1 : Configuration de l’Environnement

Pour commencer, vous devez créer une application console en C#. Cette application va inspecter vos classes et générer des scripts SQL correspondants. Voici une version simplifiée de la façon dont le code fonctionne :

  1. Charger l’Assembly : Utilisez la réflexion pour charger l’assembly contenant vos classes C#.
  2. Iterer à travers les Types : Parcourez chaque classe au sein de l’assembly et collectez ses propriétés.
  3. Créer des Scripts SQL : Pour chaque classe, générez un script SQL CREATE TABLE basé sur ses propriétés et types.

Étape 2 : Implémentation du Code

Voici le cœur de l’implémentation que vous pouvez modifier pour l’adapter à vos besoins.

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)" },
            // Ajoutez plus de correspondances si nécessaire
        };

        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();
        }
    }
}

Étape 3 : Exécution de Votre Code

Une fois que vous avez chargé l’assembly avec vos classes de données, il suffit d’exécuter le code. Il produira des scripts SQL abstraits similaires à :

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

CREATE TABLE FKClass
(
    ID BIGINT,
    AFKInt BIGINT
)

Réflexions Supplémentaires

  • Attributs pour le Filtrage : Envisagez d’ajouter un attribut personnalisé, tel que [SqlTable], à vos classes afin de vous assurer que seules les classes désignées sont converties en tables.
  • Améliorations : Le code peut être optimisé et refactorisé davantage. Par exemple, la gestion des relations de clé étrangère est assez rudimentaire et pourrait bénéficier d’une logique supplémentaire.

Cette solution fournit un point de départ robuste pour automatiser la génération de tables SQL en fonction des structures de classe C#. Bon codage !