0

これは、データ エンティティ、ドメイン オブジェクト、ViewModel 間のマッピングに関する一般的な質問です。私はそれを正しく尋ねていないかもしれませんが、うまくいけば、私はそれをある程度理解することができます. 以下は簡単な問題です。

データベース テーブルに 1 対 1 でマップする Entity Framework モデルがあるとしますが、ドメイン オブジェクトは同一ではない可能性があり、ViewModel は再び大幅に異なります。疑似例として:

データベース/EF エンティティ:

  • メンバーシップアカウント
  • メンバーシップアカウントExtraInfo

ドメイン:

  • アカウント
  • プロフィール
  • 環境設定

ビューモデル:

  • ユーザープロファイルモデル

UserProfileModel を表示する必要があるとしましょう: Username ( MembershipAccount から)、 SignupDate ( MembershipAccount から)、 FullName ( MembershipAccountExtraInfo から)、および TimeZone ( MembershipAccountExtraInfo から)

ここではどのような関係が必要で、どのようなマッピングメカニズムが必要ですか? MembershipAccount と MembershipAccountExtraInfo の両方を受け取り、アカウントを返す AccountMapper のようなものを持つことは一般的ですか? 単一のドメイン エンティティを作成するために複数のオブジェクトが必要な場合、またはその逆の場合、マッピングに少し行き詰まっています。

役立つ場合: ユーザー アカウント、ユーザー プロファイル、ユーザー設定などを管理するための API を設計していますが、データベース テーブルがあちこちにあります。4 ~ 5 個のテーブルと 2 つのデータベースにまたがるデータから、単一のユーザー プロファイルを作成する必要がある場合があります。データベース テーブルと (論理) ドメイン オブジェクトの間に 1:1 のマッピングがありません。

ありがとう!

4

1 に答える 1

2

私は自分のドメイン オブジェクトを、それらが表すオブジェクトにできる限り近づけて作業するのが好きです。これが意味することは、アカウントに設定がある場合、ドメインAccountオブジェクトにはPreferencesプロパティが含まれている必要があり、ほとんどの場合、オブジェクトのコレクションによって表されるということPreferenceです。少なくとも、これはユーザーがアプリケーションのデータ構造を簡単に理解するのに役立ちます。

ビュー モデルの構築に関しては、これが最も簡単な方法です... 必要なもののプロパティを追加するだけです。どのタイプのプロパティが必要になるかは、ドメイン オブジェクトをどのように構築したかによって異なります。

ビューに質問で言及した要件があり、ドメインオブジェクトをそれらが表すオブジェクトに密接にモデル化した場合、その音によって、オブジェクトが必要になるだけAccountです。PreferenceProfile

最後に、実行する必要がある唯一の「マッピング」はLinQ、Entity Framework を使用したクエリで実行できます。この時点でテーブルを結合し、作業中のオブジェクトに必要なデータを取得します。3 つのテーブルのデータからオブジェクトをインスタンス化する例を次に示します ( を使用LinQ2SQL)。

public AudioTracks GetAudioTracks(AudioTrackSearchOptions searchOptions)
{
    AudioTracks audioTracks;
    using (MidasDataContext dataContext = DataContext)
    {
        audioTracks = new AudioTracks(
            from audioTrack in dataContext.DbAudioTracks
            join masterTrack in dataContext.DbMasterTracks on audioTrack.MasterTrackId equals masterTrack.Id
            join masterTrackArtist in dataContext.DbDataLists on masterTrack.ArtistId equals masterTrackArtist.Id
            orderby string.Concat(masterTrack.Title, " (", audioTrack.Mix, ") - ", masterTrackArtist.Text)
            where (searchOptions.IsInactiveAudioTrackIncluded || audioTrack.IsActive)
            && (searchOptions.IsDeletedAudioTrackIncluded || !audioTrack.IsDeleted)
            select new AudioTrack(audioTrack.Id, masterTrack.Id, audioTrack.Isrc, masterTrack.Title, masterTrackArtist.Text, audioTrack.Mix, audioTrack.IsContentExplicit, audioTrack.IsActive, audioTrack.IsDeleted));
    }
    audioTracks.Sort(a => a.TitleWithMix);
    return audioTracks ?? new AudioTracks();
}

更新 >>>

AudioTracks私の例を拡張して逆方向に作業すると、GetAudioTracksメソッドは というプロジェクトにありDataProvidersます。ユーザーフィードバックと再試行オプションを追加するだけGetAudioTracksのクラスのメソッドから呼び出されます。これは、アプリケーション内のさまざまなタイプのトラックに関連するクラスのメソッドのサブセクションを含むプロジェクト内のDataControllerによって呼び出されます。TracksModelModelsDataController

最後にAudioTracksViewModelViewModelsプロジェクト内のは、ユーザーが をロードしたTracksModel.GetAudioTracksときに発生する初期化時にメソッドを呼び出します。AudioTracksViewの左側には、ユーザーの検索および/またはフィルター選択に一致するすべてのオブジェクトが含まれていAudioTracksViewます。画面の右側には、選択した のフィールドがあります。これはどのように見えるかです (リンクが壊れているように見える場合は、ここで画像を表示できます):ListBoxAudioTrackAudioTrack

AudioTracksView

Button右側に編集がある透明度の高いフィールドは、コレクションに接続された読み取り専用フィールドです。編集Buttonによりダイアログが開き、ユーザーが複数の項目を入力できるようになり、それらの項目がフィールドにまとめられます。アプリケーション内のすべてのオブジェクトは、多かれ少なかれ複雑な同様のビューを持っています。

于 2013-10-30T21:59:56.160 に答える