数据实体>域对象> 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
对象,因为它将包含Preference
和Profile
对象它。
最后,需要完成的唯一“映射”可以使用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
的字段。 这是它的样子(如果链接看起来坏了,你可以在这里查看图像):
右侧带有编辑Button
的更透明的字段是连接到集合的只读字段。 编辑Button
打开一个对话框,让用户输入多个项目,然后在字段中进行汇总。 应用程序中的所有对象具有或多或少复杂性的类似视图。