c# - Web API 应用程序中的模型分离

标签 c# entity-framework asp.net-web-api domain-model

我的团队使用 Entity Framework 开发了一个网络 API 应用程序, Gui 是由一个单独的团队开发的。

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

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

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

最佳答案

一般来说,最好不要让您的实体(数据库模型)泄露出您的数据库层。但是,与软件中的所有内容一样,这也有缺点。其中一个缺点是,它开始增加数据层的复杂性,因为它涉及将实体映射到数据库层中的 DTO,最终导致充满相似方法的存储库返回不同的 DTO 类型。

有些人还认为从数据层公开 IQueryables 也是一件坏事,因为您开始将抽象泄漏到不同的层 - 尽管这似乎总是有点极端。

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

例如:

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

// Usage
BlogPostDto 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。最终,您不希望您的客户端依赖于您的数据架构,这正是您公开实体时会发生的情况。

备选方案:命令/查询分离

我还需要强调的是,对于典型的分层架构,还有其他一些替代方案,例如命令/查询隔离方法,您可以通过调解器对命令和查询进行建模。我不会详细介绍它,因为它是另一个主题,但我肯定会更喜欢上面讨论的分层方法。这将导致您直接在建模命令或查询中将您的实体映射到您的 DTO。

我建议看一下 Mediatr为了这。同样创建 AutoMapper 的作者 Jimmy Bogard 也有 this video talking关于同一主题。

关于c# - Web API 应用程序中的模型分离,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35724115/

相关文章:

java - 如何在Android中调用以final类对象作为参数的返回值方法?

c# - 如何在序列化 OData 响应时忽略 Null 值

c# - 带有 Crystal 报表的数据库登录提示

c# - 如何在 HTTP 请求正文中包含语音标记(双引号)

c# - 如何在模型绑定(bind)中使用 Group By 查询

c# - 如何首先在代码中或使用 ColumnBuilder 将 ROWGUIDCOL 属性指定为 Guid 类型的列?

c# - Thinktecture Identity v2 滚动 session 安全 token

c# - 如何在运行时设置类型时使用 Queryable.Where?

c# - Entity Framework 不将元数据嵌入到 dll 中

rest - 在 REST API 中支持多种语言