【发布时间】:2011-09-25 07:57:05
【问题描述】:
我有以下领域模型:
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。
非常感谢任何输入。
【问题讨论】:
-
请注意,您可能正在创建一个贫血的域模型。您是域对象似乎没有公开任何行为 - 它只是公共 getter 和 setter(这很危险)。
-
为了示例,我保持简单。
标签: asp.net-mvc-3 design-patterns domain-driven-design ddd-repositories data-transfer-objects