asp.net mvc 3 - Can DTO's have nested DTO's?



我有以下域模型:

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,直接将域模型传递给控制器,并结束它。但我不想这么做,因为整个目的是学习如何使用DTO。

任何意见都将不胜感激。

DTO不是数据的扁平表示,尽管它们可以是。

这就是它们的美妙之处——你可以根据需要构建它们,而不是数据库如何定义事物。此外,它们也是将数据与行为分离的一种手段。

我根本不会在DTO中引用Domain对象。(您在构造函数中有它)使用工厂来构建DTO,这样您的客户端只需要引用DTO,而不需要引用Domain对象。

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

如果您的客户端需要引用域对象,那么他们也可以使用它们!

您所做的是正确的。我认为,当您向应用程序的数据层传递数据时,它们本质上是扁平表示。

相关内容

最新更新