C# クラスから数分でデータベーステーブルを自動生成する方法

データベーステーブルを手動で作成するのは面倒な作業であり、特に多数のクラスを扱う場合はそうです。もし、長い SQL スクリプトを書くことなくテーブルを迅速に生成する必要がある場合、あなたは正しい場所にいます。このブログ投稿では、リフレクションと少しのコーディングの魔法を使って C# クラスから直接データベーステーブルを自動生成する解決策を提供します。

問題

いくつかの C# クラスがあり、アプリケーションの成長に伴い、これらのクラスに対応するデータベーステーブルを作成する必要があると想像してみてください。これらのテーブルを手動で作成するのは疲れるだけでなく、エラーが発生しやすいです。こちらは単純な 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; }
    }
}

このクラスからは、次のような SQL 文が必要になります:

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

さらに、System.Management.ManagementObject のような複雑な型をクラス内で扱うことは、Foo クラスの修正バージョンで示すように、さらに複雑にすることがあります。

解決策

ステップ 1: 環境のセットアップ

まず、C# でコンソールアプリケーションを作成する必要があります。このアプリケーションはあなたのクラスを調査し、それに対応する SQL スクリプトを生成します。以下は、コードの動作を簡略化したバージョンです:

  1. アセンブリの読み込み: リフレクションを使用して、C# クラスを含むアセンブリを読み込みます。
  2. 型の反復: アセンブリ内の各クラスをループしてそのプロパティを収集します。
  3. SQL スクリプトの生成: 各クラスに対して、そのプロパティと型に基づいた CREATE TABLE SQL スクリプトを生成します。

ステップ 2: コード実装

以下は、あなたのニーズに合わせて修正できる実装の核心部分です。

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)" },
            // 必要に応じてマッピングを追加
        };

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

ステップ 3: コードの実行

データクラスでアセンブリを読み込んだら、単純にコードを実行してください。それは抽象的な SQL スクリプトを生成します。例えば:

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

CREATE TABLE FKClass
(
    ID BIGINT,
    AFKInt BIGINT
)

追加の考慮事項

  • フィルタリングのための属性: [SqlTable] のようなカスタム属性をクラスに追加することを検討して、特定のクラスのみがテーブルに変換されるようにしましょう。
  • 拡張: コードはさらに最適化され、リファクタリングされる可能性があります。たとえば、外部キー関係の処理はかなり基本的であり、追加のロジックが必要です。

この解決策は、C# クラス構造に基づいて SQL テーブルを自動生成するための強力な出発点を提供します。コーディングを楽しんでください!