砂漠の旅人(たびと)|新天地:たびとの旅路

電脳砂漠を旅する、ある旅人の日記。フロッピーを頼りに歩いた日から、クラウドの地平を見つめる今日まで。見つけたオアシスも、迷い込んだ砂の迷宮も、全てこの羊皮紙に。

神々の神殿を巡る旅路・前編 ~Entity Framework Coreで、三柱の神々と契約する~

旅の途中、興味深いオアシスを見つけた。忘れないうちに、この羊皮紙に記しておくとしよう。

前回、ASP.NET Core 6.0とEntity Framework Coreという、新たな魔法体系の基礎に触れた。しかし、真の冒険者は、そこで立ち止まらない。この現代の統一言語が、SQLite, PostgreSQL, MySQL…それぞれに異なる理を持つ、古の神々と、果たして本当に対話できるのか?

今回は、主要なデータベースという名の神々と、Entity Framework Coreによる契約の儀式を執り行う。データベース接続以外の呪文は、可能な限り同じものを使う。果たして、神々はその魂の形(DDL)を、どのように我々に示してくれるのだろうか。これは、その違いを解き明かす、壮大な旅の、始まりの記録である。

この羊皮紙のあらまし

この羊皮紙が導く者

  • .NET 6という新たな魔法体系に、興味を抱く者
  • 各データベースという名の神々と、Entity Framework Coreの違いに興味がある探求者
  • PostgreSQLMySQLを、Dockerという名の祭壇で召喚したい冒険者

儀式の作法:Entity Framework Coreによる対話

今回の旅では、以下の四つの儀式を、それぞれの神殿で執り行う。

  • データベース削除 (EnsureDeletedAsync): 神殿を更地に戻す儀式。
  • データベース作成 (EnsureCreatedAsync): 新たな神殿を建立する儀式。
  • テーブルへの書き込み (SaveChangesAsync): 神殿に、我々の魂を捧げる儀式。
  • テーブルからの読み込み: 捧げた魂が、確かにそこに存在することを確認する儀式。

C#の呪文は、極力シンプルに。.NET 6の「最上位レベルステートメント」という、新たな詠唱法を用いる。

第一の神殿:SQLiteという名の、旅人の水筒

SQLiteは、特別な祭壇(サーバ構築)を必要としない、最も手軽な神だ。NuGetという名の魔法の袋からパッケージを授かるだけで、いつでもどこでも、その恩恵にあずかることができる。

魂を捧げる呪文

DbContextOnConfiguringで、UseSqliteと唱えるだけ。実にシンプルだ。

public class SampleContext : DbContext
{
    public DbSet<Sample> Samples { get; set; }
    protected override void OnConfiguring(DbContextOptionsBuilder options)
        => options.UseSqlite("Data Source=sample.db");
}

魂の形(DDL

儀式の後に現れたテーブルの設計図は、この通り。Idには、AUTOINCREMENTという、自動で魂に番号を振るう力が宿っている。

CREATE TABLE "Samples" (
    "Id" INTEGER NOT NULL CONSTRAINT "PK_Samples" PRIMARY KEY AUTOINCREMENT,
    "Name" TEXT NOT NULL
);

第二の神殿:PostgreSQLという名の、気品高き賢者

次に、Dockerという名の祭壇で、PostgreSQLという賢者を召喚する。

$ docker run -d --name postgres -e POSTGRES_PASSWORD=postgres -p 5432:5432 postgres

魂を捧げる呪文

この賢者は、小文字を好む。UseNpgsqlと共にUseSnakeCaseNamingConventionという呪文を唱えることで、我々の捧げる魂の形を、賢者の好みに合わせることができる。

options.UseNpgsql("host=localhost;port=5432;database=ef;...")
       .UseSnakeCaseNamingConvention();

魂の形(DDL

設計図を見れば、テーブル名もフィールド名も、全て美しいスネークケースに変換されているのがわかる。

CREATE TABLE public.samples (
    id int4 NOT NULL GENERATED BY DEFAULT AS IDENTITY,
    "name" text NOT NULL,
    CONSTRAINT pk_samples PRIMARY KEY (id)
);

第三の神殿:MySQLという名の、陽気な神

最後に、MySQLという陽気な神を、同じくDockerの祭壇に召喚する。

$ docker run -d --name mysql -e MYSQL_ROOT_PASSWORD=mysql -p 3306:3306 mysql

魂を捧げる呪文

この神との対話には、本家と、Pomeloという二つの流派が存在する。今回は、より多くの旅人に支持されている、Pomeloの作法UseMySqlを用いる。LogToなどの呪文を加えれば、神との対話の様子を、より詳細に知ることができる。

options.UseMySql("server=localhost;Database=ef;...",
                 new MySqlServerVersion(new Version(8, 0, 27)))
       .LogTo(Console.WriteLine, LogLevel.Information);

魂の形(DDL

その設計図は、文字コードへの配慮(utf8mb4)など、陽気さの中に、細やかな気配りが感じられるものだった。

CREATE TABLE `Samples` (
  `Id` int NOT NULL AUTO_INCREMENT,
  `Name` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
  PRIMARY KEY (`Id`)
) ...

羊皮紙を巻く前に

前編では、SQLite, PostgreSQL, MySQLという、三柱の神々と対話した。 驚くべきことに、DbContextUseXxxメソッドを書き換えるだけで、ほとんど同じ呪文で、異なる神々と契約を結ぶことができた。 Entity Framework Coreという現代の統一言語が、いかに強力であるかを、まざまざと見せつけられた旅だった。

後編では、今回と同様の儀式を、SQL ServerOracleという、さらに巨大な二柱の古の神々に対して執り行う。

この羊皮紙が、同じように、どの神を自らの相棒として選ぶべきか、広大な砂漠で途方に暮れている、未来の冒険者の助けとなることを願う。

おっと、どうやら相棒が腹を空かせたようだ。今日はこのへんで筆を置くとしよう。

砂漠で見つけた魔法のランプ

  • SQLite 公式の古文書
  • Npgsql (PostgreSQL用) 公式の古文書
  • Pomelo (MySQL用) の古文書
  • DBeaver | 神々と対話するための、万能な水晶玉
  • Dockerのインストールに関する古文書

ラクダの独り言

ご主人が、何やら「ぽすとぐれ」だの「まいえすきゅーえる」だの、色んな名前の神様を、次から次へと呼び出しては、同じようなお祈りを捧げている。俺に言わせりゃ、神様なんてのは、一柱いりゃ十分だろうに。まったく、人間ってのは、浮気性な生き物だ。やれやれだぜ。