情報応用演習Ⅰ(2024)

【T2e】Entity Framework Core を用いたデータベースへのアクセス(2/6)

プロジェクトタイプC#コンソールアプリ※
プロジェクト名T2e
ソリューション名PIT2
ターゲットフレームワーク.NET 8.0(長期的なサポート)
最上位レベルのステートメントを使用しない使用する(チェックオフ)

※ 「コンソールアプリ(.NET Framework)」ではないので注意せよ!

2e-2. O/Rマッピングの必要性

チュートリアル【T2d】では,Npgsqlを直接用いてデータベースへのアクセスを行った.この方法はわかりやすいが欠点も多い.

たとえば,テーブルの各行のデータは列ごとに整数や文字列といった単一の値として取り出すことしかできず, 「一人の従業員」というようなまとまった形でデータを取得することができない. このためには,「従業員」を表す_のようなクラスを作って, SQL文を実行した際に「行に含まれている情報」から「従業員」クラスへのデータの変換を行う,といった作業が必要になる (_).

「従業員」クラスの例(cf. tbl_jugyoinのテーブル定義)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
// 「従業員」クラス
class Jugyoin
{
  public int      JugyoinNo  { get; set; } // 従業員番号
  public string   Sei        { get; set; } // 姓
  public string   Mei        { get; set; } // 名
  public string   LastName   { get; set; } // 姓(英語表記)
  public string   FirstName  { get; set; } // 名(英語表記)
  public string   Email      { get; set; } // メールアドレス
  public string   PhoneNo    { get; set; } // 電話番号
  public DateTime ShugyoBi   { get; set; } // 就業日
  public string   ShokushuNo { get; set; } // 職種番号
  public int?     Kyuyo      { get; set; } // 給与
  public double?  Buai       { get; set; } // 歩合 
  public int?     KanrishaNo { get; set; } // 管理者番号
  public int?     BumonNo    { get; set; } // 部門番号

}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
-- tbl_jugyoin のテーブル定義
CREATE TABLE tbl_jugyoin
(
    jugyoin_no     DECIMAL(6,0) PRIMARY KEY NOT NULL, -- 従業員番号
    sei            VARCHAR(25)  NOT NULL,             -- 姓
    mei            VARCHAR(25)  NOT NULL,             -- 名
    last_name      VARCHAR(25)  NOT NULL,             -- 姓(英語表記)
    first_name     VARCHAR(25)  NOT NULL,             -- 名(英語表記)
    email          VARCHAR(20)  NOT NULL UNIQUE,      -- メールアドレス
    phone_no       VARCHAR(20),                       -- 電話番号
    shugyo_bi      DATE         NOT NULL,             -- 就業日
    shokushu_no    VARCHAR(10)  NOT NULL,             -- 職種番号
    kyuyo          DECIMAL(10,0),                     -- 給与
    buai           DECIMAL(2,2),                      -- 歩合
    kanrisha_no    DECIMAL(6,0),                      -- 管理者番号
    bumon_no       DECIMAL(4,0),                      -- 部門番号
    CONSTRAINT kyuyo_min CHECK( kyuyo > 0)
);
「行に含まれている情報」から「従業員」クラスへのデータの変換の例
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
var connectionString = "Host=localhost;Port=5432;Database=SampleDB_hr;Username=hr_user;Password=n1z3Lo9AQap3";

using (var conn = new NpgsqlConnection(connectionString))
{
    conn.Open(); // 接続開始

    var cmd = new NpgsqlCommand("SELECT * FROM tbl_jugyoin", conn);
    var reader = cmd.ExecuteReader();

    while (reader.Read())
    {
        // 行からクラスへの読み替え
        var jugyoin = new Jugyoin()
        {
            JugyoinNo = reader.GetInt32(0),
            Sei = reader.GetString(1),
            Mei = reader.GetString(2),
            LastName = reader.GetString(3),
            FirstName = reader.GetString(4),
            Email = reader.GetString(5),
            PhoneNo = reader[6] as string,
            ShugyoBi = reader.GetDateTime(7),
            ShokushuNo = reader.GetString(8),
            Kyuyo = reader[9] as int?,
            Buai = reader[10] as double?,
            KanrishaNo = reader[11] as int? ,
            BumonNo = reader[12] as int?,
        };

        Console.WriteLine($"jugyoin_no = {jugyoin.JugyoinNo}, sei = {jugyoin.Sei}, mei = {jugyoin.Mei}");
    }//while
}//using

テーブルごとにこのようなクラスを定義したり,SQL文の実行結果をそのようなクラスのオブジェクトとして再構築する, という作業はいかにも煩雑である.しかも_のような作業はデータがアプリとRDBMSの間を 行き来するたびに必要になる.

リレーショナルモデルは古くから確立されたデータ管理のための理論であるが,実は オブジェクト指向プログラミングと非常に相性が悪く , リレーショナルモデル部分とオブジェクト指向プログラミング部分のすり合わせにはかなりの労力がかかることが知られている. この相性の悪さをインピーダンスミスマッチ などと呼ぶことがある.

このようなすり合わせを自動的に行う技術はO/Rマッピングと呼ばれ,.NET Core にもそのようなO/Rマッピングのための技術としてEntity Framework Coreがある.

今回はNpgsqlを直接使用するのではなく,Entity Framework Coreを使ってデータベースにアクセスする方法を試してみよう. なお,このチュートリアルは前節の「接続ユーザーの準備」の作業を済ませていることを前提としているが, 前節で作業済みであれば接続ユーザーの準備作業を改めて実施する必要はない.

Last updated on 2024-04-26
Published on 2024-04-26

Powered by Hugo. Theme by TechDoc. Designed by Thingsym.