MENU

EntityFrameworkとObject – Related Mapper

目次

背景

EntityFrameworkはとても便利です。

EntityFrameworkがあるおかげで、わざわざSQL文を書かなくてもいいし、Modelクラスに合うようなテーブルを作らなくて済みます。そのため、非常に重要な、そして基本的な概念であるはずなのですが、名前からその機能を連想することは難しいし、.NETやASP.NET Coreといった似たような名前があるため、覚えづらい。(個人的には)

ということで、整理してみました。 

この記事は、「EntityFrameworkってなんぞ?」と思った過去の自分が、10分くらいで読み、「ふーん、なんとなくわかったわ」と思うような記事を書くことを目標としています。

EntityFrameworkの定義

Entity Framework(EF) はobject – relational mapperであり、.NETを用いる開発者がdomain-specific objectsを用いてリレーショナルデータを操作できるようにします。

Microsoft, “Entity Framework”. https://learn.microsoft.com/en-us/aspnet/entity-framework, 拙訳

なんだか横文字ばかりでよくわからない、というのが第一印象です。

簡単にまとめてしまうと、”モデルクラスを用いてデータベースを操作できるよ” ということになります。しかし、簡単にまとめたものを暗記するだけでは記事になりませんし、味気ない、それになんだか深みのようなものが損なわれてしまう気がする。

ということで、もう少し整理していきます。

Object – Relational Mapper

今日、オブジェクト指向を反映したプログラミング言語は多く存在しており(例, Java, PHP, C#, Python)、アプリの開発にも頻繁に用いられます。しかし、その1つの言語でアプリが開発されることはほとんどなく(おそらく)、一般的にはそれぞれのレイヤーによって、使用される言語が異なります。

MVCパターンに基づいたWebアプリの構成と使用言語の例

図はあくまで一例です。例えば、C#ではなくJavaを使っている場合もあります。また、JavaScriptは場合によっては、View以上の役割を担う気がするため、中途半端な位置にしました。

例えば、MVCパターンに基づいたWebアプリを考えた時、ControllerにはC#やJava、データベースとのやりとりにはSQLを用います。この場合、テーブルに新たな列を追加すると、モデルクラスにプロパティを追加・Viewの表示項目を追加・SQL文の条件を変更をアプリ全体で行わなければいけません。

この過程を改善するために生まれたのが、ORMになります。
ORMによって、以下のことが可能になります。

  • モデルクラスの変更をデータベースに反映する (migration)
  • モデルクラスを用いてデータを取得する

そのため、データを取得するためのSQL文を書く必要がなくなり、モデルクラスとテーブルの整合性に気を配る必要がなくなりました。

参考文献

Baeldung.com, “What Is an ORM? How Does It Work? How Should We Use One?”, https://www.baeldung.com/cs/object-relational-mapping, 2023/10/15

EntityFrameworkの使用例

バスケットボール選手のイラストには、Mohamed_hassanさんのものを使用した

最後に、EntityFramework (EF) を使用した場合と使用しない場合の差を見ていきます。例として、バスケットボール選手を管理するアプリの選手クラス(データ)を想定します。

テーブルの作成

EF使用

EntityFrameworkを使用する場合は、モデルを作成 → migration → データベースの更新、という流れになります。ただし、migrationとデータベースの更新は、パッケージマネージャーコンソールでコマンドを1つ打つだけになっており、下記のようになります。

PM> add-migration
PM> update-database

add-migrationは、モデルクラスの内容からテーブルの作成に必要なコードを作成します。このコードは1つのファイルに書き出され、migration fileと呼びます。update-databaseはmigration fileをもとに、データベースの更新を行います。ちなみに、前の状態に戻したい場合は、戻したい状態の時のmigration fileを引数に指定することによって、戻すことができます。

migration fileを取得するには、get-migrationが便利です。get-migrationは利用可能なmigration fileのリストを返してくれます。

PM> get-migration

id                          name         safeName     applied
--                          ----         --------     -------
20231030211857_CreateDbver1 CreateDbver1 CreateDbver1    True
20231030212036_CreateDbver2 CreateDbver2 CreateDbver2    True

上記の例では、CreateDbver1とCreateDbver2という2つのmigrationファイルがあり、下の方が最近作成したものになります。例えば、既にCreateDbver2ファイルを用いて、データベースを更新(update-database)してしまったが、CreateDbver1の状態に戻したいという場合は、idを指定してデータベースを更新します。

update-database "20231030211857_CreateDbver1"

そのあと、CreateDbver2が不要であれば削除しても構いません。

SQL文

public class Player
    {
        [Key]
        public int PlayerId { get; set; }
        public int Number { get; set; }
        public float Height { get; set; }
        public float Weight { get; set; }
    }

上記のモデルクラスに対応するテーブルを作成するSQL文をChatGPTに聞いてみました。

CREATE TABLE [Players] (
    [PlayerId] INT NOT NULL IDENTITY,
    [Number] INT NOT NULL,
    [Height] REAL NOT NULL,
    [Weight] REAL NOT NULL,
    CONSTRAINT [PK_Players] PRIMARY KEY ([PlayerId])
);

これくらいではそれほど多くない。しかし、例えば10個のプロパティを持ったクラスが30個ある場合、それなりの時間がかかることが想像できます。一方で、SQL文を使うとすぐに解決できることが、EFを使うと調査に時間がかかってしまう、という場合もあるかもしれませんが・・・。

テーブル作成のほかに、データの取得・追加・修正・削除(CRUD)といった場合にも、EntityFrameworkを使用することができます。個人的には、C#ですべて書くことができることを気に入っていますが、SQL文の無骨さに触れられないのを少し寂しく思います。

しかし、作成スピードや読みやすさを考えると、断然EntityFrameworkだと思いますし、書いていて楽しいというのは、仕事では2の次なのかな、とも思います。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする

CAPTCHA


目次