C# · 12月 24, 2021

c# – 在web api应用程序中分离模型

我的团队使用实体框架开发了一个web api应用程序,
Gui由一个独立的团队开发.

我的问题是如何定义模型?我们应该有两个项目 – 一个用于域模型(数据库实体),一个用于可序列化的Dtos?

从Dto到域模型的解析应该在哪里发生?何时应该以相反的方式发生?

此外,有时需要将所有数据发送给客户端..是否应该为这些情况创建Dto?或者我应该返回域模型?

解决方法 一般来说,不要让您的实体(数据库模型)泄漏出数据库层是个好主意.然而,就像软件中的所有内容一样 – 这可能会导致其崩溃.其中之一就是它开始增加数据层的复杂性,因为它涉及将您的实体映射到数据库层中的DTO,最终留下充满类似方法的存储库返回不同的DTO类型.

有些人还认为,当您开始将抽象泄漏到不同的层时,从数据层中暴露IQueryables也是一件坏事 – 尽管这似乎有点极端.

就个人而言,我赞成我认为更实用的方法,我更喜欢使用像AutoMapper这样的工具来自动将我的实体映射到业务逻辑层中的DTO.

例如:

// Initial configuration loaded on start up of application and cached by AutoMapperAutoMapper.Mapper.CreateMap<BlogPostEntity,BlogPostDto>();// UsageBlogPostDto blogPostDto = AutoMapper.Mapper.Map<BlogPostDto>(blogPostEntity);

AutoMapper还能够配置更复杂的映射,但是如果可能的话,你应该尽量避免这种情况,坚持使用更平坦的DTO.

此外,AutoMapper的另一个重要功能是能够自动将您的实体投影到DTO.这样可以使sql更清晰,只查询DTO中的列:

public IEnumerable<BlogPostDto> GetRecentPosts(){ IEnumerable<BlogPostDto> blogPosts = this.blogRepository.FindAll().Project(this.mappingEngine).To<BlogPostDto>().ToList(); return blogPosts;}

Moreover,sometimes all the data is needed to be sent to the clients.. Should a Dto be created for those cases as well? Or should I return a domain model?

应该为那些人创建DTO.最终,您不希望您的客户端取决于您的数据架构,这正是您公开实体时会发生的情况.

替代方案:命令/查询隔离

我还应该强调,除了典型的分层体系结构之外,还有其他一些替代方案,例如Command / Query Segregation方法,您可以通过中介对命令和查询进行建模.我不会详细介绍它,因为它是一个完整的其他主题,但我绝对赞成通过上面讨论的分层方法.这将导致您直接在建模的命令或查询中将实体映射到DTO.

我建议你看看Mediatr.同时创建AutoMapper的作者Jimmy Bogard也有关于同一主题的this video talking.