2011-01-03 7 views
19

私はAutoMapperを使用して、自分のドメインモデルを私のDTOにマッピングするだけでなく、DTOをドメインモデルにマッピングしています。子コレクションを含むDTOをドメインモデルにマッピングするためのデザインパターン

私は自分のORMにEF4を使用していますが、マッピングされているモデルに追加/更新/削除が必要な子コレクションが含まれていると、このマッピングは実際には醜いものになります。私は私のプロジェクトで前進しながら、私はブログ記事の写真、注文のためのパッケージなど、この問題にもっと取り組んでいます。DTO->ドメインモデルから行くと、 BeforeMapコールは、ドメインモデルのコレクションからすべてのエンティティを削除し、DTOから各エンティティのPKを取得するコレクション用のカスタムValueResolverを追加して、DBから取得します(エンティティフレームワークでは、新しいエンティティ)を作成し、それをドメインモデルのコレクションに再度追加し、個々のフィールドに更新を適用します。

これは本当に醜い解決策ですが、手動でこれらのコレクションの更新を処理しようとしています。誰もよりクリーンなアプローチの提案はありますか?

+0

Automapperを使用してドメインモデルをマッピングすると、ドメイン駆動設計を使用していない可能性があります。ただ言って。 – jfar

+1

私はいくつかの自動マジックマッピングソリューションを使ってこのマッピングをきれいに処理したいと思うのは現実的ではありませんか?純粋に自分のドメインモデルを自分のDTOから更新するためのサービスを作成する必要がありますか? – inolen

+0

@jfarあなたはどのように考えますか?まず、ドメインモデルはDDDと同義ではありません。ドメインモデルをマッピングするべきではないことを暗示し、「ドメイン駆動設計を使用しない」としてこれを取り除き、それ以上の説明をしてもそれほど有用ではないようです。階層化されたアーキテクチャでは、サービスレイヤがドメインモデルの上に位置することは珍しくありません。また、サービスレイヤーがトランスレートオブジェクトを介してドメイン、UIおよび他のレイヤーと通話することも珍しくありません。これらのレイヤーの間に「明るい線」を維持するのに役立ちます。 – nerraga

答えて

3

この機能には、AutoMapperの代わりにValueInjecterを使用します。両方のメーカーの体重がAutoMapper vs ValueInjecterのこの質問をチェックしてください。私はValue Injecterを個人的に使っていませんが、あなたがやろうとしていることをするために作られたものです。AutoMapperは平坦化には適していますが、AutoMapperの作者は、あなたがしようとしている「非平坦化」のための良いツールではないことを認めています。

1

デタッチされたオブジェクトグラフを更新するのが非常に悪いので、まずデータベースから実際のオブジェクトグラフを読み込み、手動でこのオブジェクトグラフに自分のDTOをマージします。私は通常、DTO(またはビューモデル)をDomainオブジェクトにマージするメソッドでいくつかのヘルパーMergerクラスを作成します。私はまだもっと良い解決策を探しています。

私はデータベースからオブジェクトグラフを最初にロードしなかったソリューションを試しました。その代わりに私は、分離されたドメインオブジェクトグラフを構築するためにカスタムアダプターを使用し、それをコンテキストに添付して、すべてのオブジェクトおよびリレーションの状態を設定しました。しかし、それは間違っており、すべてのシナリオで使用することができない非常に複雑な方法でした(更新の組み合わせとサブ状態の挿入は、初期状態に関する追加の転送データなしでは処理できませんでした)。休止状態で

+0

私は一人ではないと聞くのは良いことです。 私のオートマッパーで私の具体的なリポジトリを参照することは本当に悪いですが、私はIoCを使ってテスト可能なユニットを作成することを望んでいません(私は通常リポジトリをコンストラクタパラメータとして扱います)。 複雑なケースでは、DTOをマージするためにこれらのサービスクラスを作成することができますが、シンプルなケースではAutoMapperを使用し続けると思いますが、それもsortof weakと思われます。 私は一貫したデザインパターンを全面的に使用したいと思っています。 – inolen

+0

私が取り組んでいるプロジェクトのように聞こえるのは、私たちのDTOから値を読み込む前に、すべての分離されたエンティティに問い合わせる必要があるように見えるところです。私はそれが "間違っている"と感じているので、なぜ更新を実行する前にクエリを行う必要がありますか?私はLazy Loadingの拡張形式が私のエンティティのプロパティが自分のDTOから設定されていないドメインに信号を送り、必要に応じてDBからフェッチすることができるかどうか疑問に思っています。私はこれをT4テンプレートにすることができましたが、もう一度、私はEntity Framework for Microsoftを書いているように感じます... –

1

私はNHibernateのは、同様のcascadeAllオプションを持っていると思う子どもたちへの更新が..

カスケードオプションがあります。

0

DTOの子コレクションがおそらく最新バージョンの であると仮定して中継できる場合は、実際に古い コレクションを新しいものに置き換えることができます。 DTOのidを使用してデータベースからエンティティを引っ張って

  1. 使用ConstructWith:

    私たちは、NHibernateのと同じ問題があったと 我々はこのようにそれを解決しました。

  2. BeforeMapを使用して、子コレクション全体を消去します( 子の参照もnullに設定されていることを確認してください)。
  3. AutoMapperは新しいコレクションを自動的にコピーします。

幸運なことに、NHibernateは変更を適用するのに十分なほどスマートでしたが、私は EFが同じことをするかどうかを教えてくれません。 これは完璧な解決策ではありませんが、単純なドメインモデルでは機能します。

関連する問題