トラック
/
C#
C#
/
演習
/
オブジェクト関係マッピング
オブジェクト関係マッピング

オブジェクト関係マッピング

学習演習

はじめに

リソースの解放

あるクラスがIDisposableインターフェースを実装している場合、そのインスタンスが不要になったときは、必ずDispose()メソッドを呼び出す必要があります。通常は、catch節やfinally節から、あるいは呼び出し元のDispose()ルーチンから呼び出します。Dispose()は、オペレーティングシステムのオブジェクト(.NETランタイムには管理されていないもの)のようなアンマネージドリソースを解放し、マネージドリソースの内部状態をリセットするための機会になります。

説明

別のチームが用意したデータベースの上に、ORM(Object Relational Mapping)システムを実装します。

このデータベースは、一度に1つのトランザクションだけを処理できます。

この段階では、ログ出力やその他のエラー処理は必要ありません。

内部的には、データベースはいくつかの状態を遷移することに注意してください。Closed、TransactionStarted、DataWritten、Invalid、Closedです。各演習の開始時点では、データベースがClosed状態にあると考えてかまいません。

データベースには、次のインスタンスメソッドがあります。

  • Database.BeginTransaction()は、データベース上でトランザクションを開始します。データベースがClosed状態でないときにこれを呼び出すと、例外がスローされます。成功すると、データベースの内部状態はTransactionStartedに変わります。
  • Database.Write(string data)は、トランザクション内でデータベースにデータを書き込みます。不正なデータを受け取ると、例外がスローされます。BeginTransaction()を呼び出さずにこのメソッドを呼び出そうとすると、例外がスローされます。成功すると、データベースの内部状態はDataWrittenに変わります。
  • Database.EndTransaction()は、トランザクションをデータベースにコミットします。トランザクションを閉じられない場合や、Database.BeginTransaction()が呼び出されていなかった場合には、例外をスローすることがあります。
  • Database.Dispose()を呼び出すと、トランザクション中に例外がスローされたときにデータベースをクリーンアップします。これにより、データベースの状態はClosedに変わります。

データベースの状態には、database.DbStateを使ってアクセスできます。

データベースの状態は、次のいずれかに設定できます。

  • TransactionStarted
  • DataWritten
  • Invalid
  • Closed

1. トランザクションを開始する

Orm.Begin()を実装して、データベース上でトランザクションを開始します。データベースの内部状態がState.Closedで始まっていない場合は、InvalidOperationExceptionをスローします。

var orm = new Orm(new Database());
orm.Begin();
// => database has an internal state of State.TransactionStarted

2. データベースにデータを書き込む

Orm.Write()を実装して、データベースにデータを書き込みます。データベースの内部状態がState.TransactionStartedで始まっていない場合、または不正なデータが書き込まれた場合は、InvalidOperationExceptionがスローされます。書き込みが失敗したら、Ormはデータベースをクリーンアップしなければなりません。

var orm = new Orm(new Database());
orm.Begin();
orm.Write("some data");
// => database has an internal state of State.DataWritten
orm.Write("bad write");
// => database has an internal state of State.Closed

3. 以前に書き込んだデータをデータベースにコミットする

Orm.Commit()を実装して、データをコミットします。コミットが失敗したら、データベースをクリーンアップします。データベースの内部状態がState.DataWrittenで始まっていない場合は、InvalidOperationExceptionがスローされます。

var orm = new Orm(new Database());
orm.Begin();
orm.Write("some data");
orm.Commit();
// => database has an internal state of State.Closed
orm.Begin();
orm.Write("bad commit");
orm.Commit();
// => database has an internal state of State.Closed

4. トランザクションの途中でORMを閉じなければならない場合に、データベースが正しくクリーンアップされるようにする

OrmクラスにIDisposableインターフェースを実装します。この呼び出しは必ず成功します。

var db = new Database();
var orm = new Orm(db);
orm.Begin();
orm.Write("some data");
orm.Dispose();
// => database has an internal state of State.Closed
GitHubで編集する リンクは新しいウィンドウまたはタブで開きます
C# Exercism

オブジェクト関係マッピングを始める準備はできましたか?

Exercismに登録すれば、62個のコンセプト178個の演習、そして本物の人間によるメンタリングとともに、C#を学んでマスターできます。すべて無料です。