数据实体>域对象> ViewModels,每个都具有截然不同的数据结构

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

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

数据库/ EF实体:

  • MembershipAccount
  • MembershipAccountExtraInfo

域:

  • 帐户
  • 轮廓
  • 喜好

视图模型:

  • UserProfileModel

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

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

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

谢谢!

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

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

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

最后,需要完成的唯一“映射”可以使用entity framework使用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的项目中。 它是从DataController类中的GetAudioTracks方法调用的,它只添加用户反馈和重试选项。 反过来,它由Models项目中的TracksModel调用, TracksModel包含DataController类中与应用程序中各种类型的轨道相关的方法的子部分。

最后, ViewModels项目中的TracksModel.GetAudioTracks在初始化时调用TracksModel.GetAudioTracks方法,该方法在用户加载AudioTracksView时发生。 AudioTracksView有一个ListBox ,其中包含符合用户搜索和/或过滤选择的所有AudioTrack对象。 屏幕右侧包含所选AudioTrack的字段。 这是它的样子(如果链接看起来坏了,你可以在这里查看图像):

AudioTracksView

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