数据实体域对象ViewModels,每个都有截然不同的数据结构 [英] Data Entities > Domain Objects > ViewModels, each with drastically different data structures

查看:23
本文介绍了数据实体域对象ViewModels,每个都有截然不同的数据结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

This is sort of a generic question in regards to mapping between data entities, domain objects, and ViewModels. I may not be asking it right but hopefully I can make some sense of it. Below is a simplified problem.

假设我有一个实体框架模型,它以 1:1 的比例映射到我的数据库表,但我的域对象可能不相同,而我的 ViewModel 又完全不同.作为一个伪示例:

Pretend I have an Entity Framework model which maps 1:1 to my database tables, but my domain objects may not be identical, and my ViewModel is drastically different again. As a pseudo-example:

数据库/EF 实体:

  • 会员帐户
  • MembershipAccountExtraInfo

域:

  • 帐户
  • 个人资料
  • 偏好设置

视图模型:

  • 用户配置文件模型

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

Let's say I need to display a UserProfileModel which has: Username (from MembershipAccount), SignupDate (from MembershipAccount), FullName (from MembershipAccountExtraInfo), and TimeZone (from MembershipAccountExtraInfo)

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

What sort of relationships might I need here, and what sort of mapping mechanisms? Is it common to have something like an AccountMapper that takes both a MembershipAccount and MembershipAccountExtraInfo and returns an Account? I'm a bit stuck on the mapping when several objects are needed to create a single domain entity, and vice versa.

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

If it helps: I'm designing an API for managing User Accounts, User Profiles, User Preferences, etc. but the database tables are all over the place. A single User Profile might need to be created from data spanning 4-5 tables and 2 databases. There is no 1:1 mapping between my database tables and any (logical) domain objects.

谢谢!

推荐答案

我喜欢让我的领域对象尽可能接近它们所代表的对象.我的意思是,如果一个帐户有首选项,那么域 Account 对象应该包含一个 Preferences 属性,最有可能由 Preference<的集合表示/代码> 对象.如果不出意外,这有助于用户轻松理解应用程序的数据结构.

I like to work keeping my domain objects as close to the objects that they represent as possible. What I mean by this is that if an account has preferences, then the domain Account object should contain a Preferences property, most likely represented by a collection of Preference objects. If nothing else, this helps the users understand the data structure of the application easily.

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

As for constructing the view models, that's the easiest bit... you add just properties for anything that is required. What types of properties you would need would really depend on how you have structured your domain objects.

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

If your view has the requirements that you mentioned in your question and you modelled your domain objects closely on the objects that they represent, then by the sounds of it, you would just need an Account object because that would contain the Preference and Profile objects inside it.

最后,唯一需要完成的映射"可以通过使用实体框架的 LinQ 查询来完成.正是在这一点上,我加入了表格并提取了我正在处理的任何对象所需的任何数据.下面是从三个表中的数据实例化对象的示例(使用 LinQ2SQL):

Finally, the only 'mapping' that needs to be done can be done with a LinQ query using the Entity Framework. It is at this point that I join the tables and pull whatever data that I need for whichever object I am working on. Here is an example of instantiating objects from data from three tables (using 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();
}

<小时>

更新>>>


UPDATE >>>

扩展我的 AudioTracks 示例并向后工作,GetAudioTracks 方法位于名为 DataProviders 的项目中.它从 DataController 类中的 GetAudioTracks 方法调用,该类只添加用户反馈和重试选项.它又由 Models 项目中的 TracksModel 调用,该项目仅包含来自 DataController 类的与各种类型相关的方法的子部分应用程序中的曲目.

Extending my AudioTracks example and working backwards, the GetAudioTracks method is in a project called DataProviders. It is called from a GetAudioTracks method in a DataController class which just adds user feedback and re-try options. That in turn is called by a TracksModel in the Models project which just contains a subsection of methods from the DataController class that relate to the various types of tracks in the application.

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

Finally, the AudioTracksViewModel in the ViewModels project calls the TracksModel.GetAudioTracks method upon initialisation which happens when the AudioTracksView is loaded by the user. The AudioTracksView has a ListBox on the left containing all of the AudioTrack objects that meet the users search and/or filter selections. The right of the screen has the fields for the selected AudioTrack. Here is what it looks like (if the link seems broken, you can view the image here):

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

The more transparent fields with an edit Button on the right are read only fields connected to collections. The edit Button opens a dialog to let the user enter multiple items, which are then summarised in the field. All of the objects in the application have similar views of more or less complexity.

这篇关于数据实体域对象ViewModels,每个都有截然不同的数据结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆