0

这是一个关于数据实体、域对象和 ViewModel 之间映射的通用问题。我可能问得不对,但希望我能理解它。下面是一个简化的问题。

假设我有一个 Entity Framework 模型,它将 1:1 映射到我的数据库表,但我的域对象可能不完全相同,并且我的 ViewModel 再次完全不同。作为一个伪示例:

数据库/EF 实体:

  • 会员帐户
  • MembershipAccountExtraInfo

领域:

  • 帐户
  • 轮廓
  • 喜好

视图模型:

  • 用户档案模型

假设我需要显示一个 UserProfileModel,它具有:用户名(来自 MembershipAccount)、SignupDate(来自 MembershipAccount)、FullName(来自 MembershipAccountExtraInfo)和 TimeZone(来自 MembershipAccountExtraInfo

我在这里可能需要什么样的关系,什么样的映射机制?是否有像 AccountMapper 这样的东西,它同时接受 MembershipAccount 和 MembershipAccountExtraInfo 并返回一个 Account?当需要多个对象来创建单个域实体时,我有点卡在映射上,反之亦然。

如果有帮助:我正在设计一个用于管理用户帐户、用户配置文件、用户首选项等的 API,但数据库表无处不在。可能需要从跨越 4-5 个表和 2 个数据库的数据创建单个用户配置文件。我的数据库表和任何(逻辑)域对象之间没有 1:1 映射。

谢谢!

4

1 回答 1

2

我喜欢使我的域对象尽可能接近它们所代表的对象。我的意思是,如果一个帐户有偏好,那么域Account对象应该包含一个Preferences属性,很可能由一组Preference对象表示。如果不出意外,这有助于用户轻松理解应用程序的数据结构。

至于构建视图模型,这是最简单的一点……您只需为所需的任何内容添加属性。您需要哪些类型的属性实际上取决于您如何构建域对象。

如果您的视图具有您在问题中提到的要求,并且您在它们所代表的对象上密切建模您的域对象,那么从它的声音来看,您只需要一个Account对象,因为其中将包含PreferenceandProfile对象。

最后,唯一需要完成的“映射”可以通过LinQ使用实体框架的查询来完成。正是在这一点上,我加入了表格并提取了我正在处理的任何对象所需的任何数据。以下是从三个表中的数据实例化对象的示例(使用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只是添加用户反馈和重试选项。这又由项目中的 a 调用,TracksModelModels项目仅包含DataController类中与应用程序中各种类型的轨道相关的方法的子部分。

最后,项目AudioTracksViewModel中的初始化时ViewModels调用该方法,这在用户加载时发生。左侧有一个包含所有满足用户搜索和/或过滤选择的对象。屏幕右侧有选定的字段。这是它的样子(如果链接似乎断开,您可以在此处查看图像):TracksModel.GetAudioTracksAudioTracksViewAudioTracksViewListBoxAudioTrackAudioTrack

音轨视图

右侧带有编辑的更透明字段Button是连接到集合的只读字段。编辑Button会打开一个对话框,让用户输入多个项目,然后在字段中进行汇总。应用程序中的所有对象都具有或多或少复杂的相似视图。

于 2013-10-30T21:59:56.160 回答