15

私は次のドメインモデルを持っています:

public class Playlist
{
    public long Id { get; set; }
    public string Title { get; set; }
    public virtual ICollection<Song> Songs { get; set; }
}

public class Song
{
    public long Id { get; set; }
    public string Name { get; set; }
    public virtual Playlist Playlist { get; set; }
    public virtual ICollection<Catalog> Matches { get; set; }
}

public class Catalog
{
    public long Id { get; set; }
    public string Title { get; set; }
}

私のサービスには次のコードがあります。

public PlaylistResult FindByPlaylistId(long id)
{
    Playlist playlist = playlistRepository.GetById(id);

    foreach (var song in playlist.Songs)
    {
        song.Matches = catalogRepository.GetMatches(song.Name).ToList();
    }

    return new PlaylistResult(new PlaylistDTO(playlist), playlist.Songs.Select(x => new SongDTO(x)));
}

私のサービスはデータベースからプレイリストと曲を取得し、プレイリスト内の曲ごとにクエリを実行して、その曲に固有のデータベースから追​​加の一致を取得します(SQL Server全文検索を使用)。

次に、データはDTOに変換され、結果オブジェクトに追加されて、コントローラーに戻されます。コードは次のようになります。

public class PlaylistResult
{
    public PlaylistResult(PlaylistDTO playlist, IEnumerable<SongDTO> songs)
    {
        Playlist = playlist;
        Songs = songs;
    }

    public PlaylistDTO Playlist { get; private set; }

    public IEnumerable<SongDTO> Songs { get; private set; }
}

問題:

これまでのところ、PlaylistResultオブジェクトはうまく機能しましたが、最近の一致の導入により、状況は少し複雑になりました。一致を考慮してSongDTOを変更し、次のようにする以外に選択肢はないようです。

public class SongDTO
{
    public SongDTO(Song song, IEnumerable<CatalogDTO> matches)
    {
        Id = song.Id;
        Name = song.Name;
        Matches = matches;
    }

    public long Id { get; private set; }

    public string Name { get; private set; }

    public IEnumerable<CatalogDTO> Matches { get; private set; }
}

しかし、これはDTOの目的に違反しませんか?DTOはデータのフラット化された表現であり、このアプローチはフラット化されていないことを理解しています。一方、各試合は各曲に固有であるため、他にこれを行う方法がわかりません。

私はこれを自分で簡単にし、DTOを破棄し、ドメインモデルをコントローラーに直接渡して1日と呼ぶことができることを認識しています。しかし、全体の目的はDTOの操作方法を学ぶことなので、私はそれをしたくありません。

どんな入力でも大歓迎です。

4

2 に答える 2

13

DTOは、データのフラット化された表現ではありませんが、フラット化された表現である可能性があります。

それがそれらの美しさです。データベースが物事を定義する方法とは対照的に、必要に応じてそれらを構造化することができます。また、それらはデータを行動から分離する手段でもあります。

ドメインオブジェクトへの参照をDTO内に配置することはまったくありません。(コンストラクターにあります)ファクトリを使用してDTOを構築し、クライアントがDTOを参照するだけで、ドメインオブジェクトを参照する必要がないようにします。

 Song mySong;
 SongDTO = DTOFactory.GetSong(mySong);

クライアントがドメインオブジェクトを参照する必要がある場合は、それらを使用することもできます。

于 2011-06-29T16:44:07.343 に答える
1

あなたがしたことは正しいです。アプリケーションのデータレイヤーとの間でデータをやり取りする場合、これらは基本的にフラット化された表現だと思います。

于 2011-06-30T09:07:27.123 に答える