私が取り組んでいる現在のシステムでは、Castle Activerecord を利用して、ドメイン オブジェクトとデータベース間の ORM (オブジェクト リレーショナル マッピング) を提供しています。これはすべてうまくいき、ほとんどの場合、実際にうまく機能します。
この問題は、Castle Activerecords の非同期実行のサポート、具体的にはオブジェクトが属するセッションを管理する SessionScope で発生します。要するに、悪いことが起こります!
そのため、ドメイン オブジェクト (DB が存在することを知っていて気にする) から DTO オブジェクト (DB について何も知らず、セッション、マッピング属性などを気にしない) に簡単に変換する (自動的に考える) 方法を探しています。 ORM)。
誰でもこれを行うことについて提案がありますか。まず、オブジェクトの基本的な一対一のマッピングを探しています。ドメイン オブジェクトPersonはPersonDTOと言うようにマッピングされます。もったいないので手動でやりたくありません。
当然反省が頭に浮かびますが、このサイトに出回っているより優れた IT 知識から、「よりクールな」 提案が得られることを期待しています。
ああ、Castle ActiveRecord にマップされる前に述べたように、ORM オブジェクトである C# で作業しています。
コード例:
@ajmastrean のリクエストにより、私が (ひどく) 一緒に嘲笑した例にリンクしました。この例には、キャプチャ フォーム、キャプチャ フォームコントローラ、ドメインオブジェクト、activerecordリポジトリ、および非同期ヘルパーが含まれています。実行に必要な ActiveRecored dll を含めたため、少し大きい (3MB) です。ローカル マシンにActiveRecordAsyncというデータベースを作成するか、.config ファイルを変更する必要があります。
例の基本的な詳細:
キャプチャフォーム
キャプチャ フォームにはコントローラへの参照があります
private CompanyCaptureController MyController { get; set; }
フォームの初期化時に MyController.Load() private void InitForm () { MyController = new CompanyCaptureController(this); を呼び出します。MyController.Load(); これは LoadComplete() というメソッドに戻ります
public void LoadCompleted (Company loadCompany)
{
_context.Post(delegate
{
CurrentItem = loadCompany;
bindingSource.DataSource = CurrentItem;
bindingSource.ResetCurrentItem();
//TOTO: This line will thow the exception since the session scope used to fetch loadCompany is now gone.
grdEmployees.DataSource = loadCompany.Employees;
}, null);
}
}
これは、遅延ロードとして設定された Company の子リストを使用しているため、 「悪いこと」が発生する場所です。
コントローラー
コントローラーには、フォームから呼び出された Load メソッドがあり、Asyc ヘルパーを呼び出して LoadCompany メソッドを非同期的に呼び出し、Capture フォームの LoadComplete メソッドに戻ります。
public void Load ()
{
new AsyncListLoad<Company>().BeginLoad(LoadCompany, Form.LoadCompleted);
}
LoadCompany() メソッドは、単純にリポジトリを利用して既知の会社を見つけます。
public Company LoadCompany()
{
return ActiveRecordRepository<Company>.Find(Setup.company.Identifier);
}
例の残りの部分は一般的なもので、基本クラスから継承する 2 つのドメイン クラス、データを挿入するためのセットアップ ファイル、およびActiveRecordMediator機能を提供するためのリポジトリがあります。