2

DTO パターンを使用して、ドメイン オブジェクトをサービス レイヤーからリポジトリにマーシャリングし、NHibernate を介してデータベースにダウンします。

DTO をレポジトリ (CustomerDTO など) から取り出して、それをサービス層のドメイン オブジェクト (Customer) に変換するという問題に遭遇しました。次に、同じ Customer オブジェクトを含む新しいオブジェクト (SalesOrder など) を保存しようとします。これは、リポジトリにプッシュするために、SalesOrderDTO (および CustomerDTO) に変換されます。

NHibernate はこれを気に入らず、CustomerDTO が重複レコードであると文句を言います。これは、同じセッションで最初の CustomerDTO が引き出され、返されたものが前後に変換されたため、これを同じオブジェクトとして認識できないためであると想定しています。

私はここで立ち往生していますか、これを回避する方法はありますか?

ありがとう

ジェームズ

4

4 に答える 4

2

他の人が指摘しているように、EqualsとGetHashCodeの実装は正しい方向への一歩です。また、「アタッチ」OR/Mイディオムに対するNHibernateのサポートも調べてください。

また、nosetter.camelcaseオプションを自由に使用できます:http://davybrion.com/blog/2009/03/entities-required-properties-and-properties-that-shouldnt-be-modified/

さらに、オンラインでの情報不足に惑わされないようにお願いしたいと思います。それはあなたが頭がおかしい、または間違ったことをしているという意味ではありません。エッジケースで作業していることを意味します。残念ながら、NHibernateのようなライブラリの最大の消費者は、小規模な社内アプリやWebアプリであり、単一のデータベースに対してすべての永続性のニーズに頼る自由があります。実際には、この規則には多くの例外があります。

たとえば、私は現在、ドメインオブジェクトの1つがSQLCEデータベースとディスク上のイメージファイルの間にデータを分散している商用デスクトップアプリに取り組んでいます。残念ながら、NHibernateはSQLCEの永続性についてのみ私を助けることができます。ある種の「ダブルマッピング」(Martin Fowlerの「エンタープライズアプリケーションアーキテクチャのパターン」を参照)を使用せざるを得ず、NHibernateに送られるデータとディスクに送られるデータを知っているリポジトリレイヤーを介してドメインモデルをマッピングします。

それは起こります。それは本当に必要です。ツールが明らかに不足している場合は、悪いアプローチを取っていることを示していることがあります。しかし、時には真実は、あなたが本当にエッジケースにあり、それを成し遂げるためにあなた自身のためにこれらのパターンのいくつかを構築する必要があるということです。

于 2009-06-03T18:38:34.487 に答える
2

NHibernate セッションがどのように機能するかについてです。したがって、セッション内で CustomerDTO のインスタンスをプルし、しばらくしてから同じ CustomerDTO を取得する必要がある場合 (たとえば、主キーで)、実際には、最初の取得で行ったのとまったく同じオブジェクトへの参照を取得します。

したがって、session.Merge を呼び出してオブジェクトをマージするか、session.Get(primaryKey) を呼び出してセッションにオブジェクトを要求し、更新を行ってセッションをフラッシュします。

ただし、スティーブが提案したように-これは通常、あなたが行うことではありません-データストアからドメインオブジェクトを取得し、(必要に応じて) DTO を使用してデータを UI や Web サービスに転送したい...

于 2009-05-14T09:02:51.420 に答える
2

Lock を使用して、NHibernate のセッションにオブジェクトを再アタッチできます。

_session.Lock(myDetachedObject, NHibernate.LockMode.None);

ここで何が起こっているかによって、これが役立つ場合とそうでない場合があります。余談ですが、NHibernate で DTO を使用することは最も一般的な方法ではありません。NHibernate が (ほとんどの場合) 永続性の無視をサポートしているという事実は、通常、DTO が他の ORM フレームワークほど広く使用されていないことを意味します。

于 2009-05-14T08:28:05.653 に答える
1

これは、同じセッションで最初の CustomerDTO が引き出され、返されたものが前後に変換されたため、これを同じオブジェクトとして認識できないためであると想定しています。

あなたが正しいです。ハイバネートはできません。これを修正するには、Equals と Hashcode を実装することを検討してください。このセッション内でオブジェクトをロードしていない場合にのみ、再接続が機能すると思います。

于 2009-05-14T18:23:48.420 に答える