C# EF核心、服务和存储库模式
为了了解模式,我正在使用以下项目创建Web API: 实体、存储库、服务和API应用程序 API中的每个控制器对其相应的服务使用依赖注入;每个服务使用DI访问多个存储库;存储库用于从DbContext获取数据,实体包含DbContext和dbset 例如,当我调用/teams/1端点时:C# EF核心、服务和存储库模式,c#,entity-framework,repository-pattern,C#,Entity Framework,Repository Pattern,为了了解模式,我正在使用以下项目创建Web API: 实体、存储库、服务和API应用程序 API中的每个控制器对其相应的服务使用依赖注入;每个服务使用DI访问多个存储库;存储库用于从DbContext获取数据,实体包含DbContext和dbset 例如,当我调用/teams/1端点时: 控制器调用\u teamService.GetTeam(id)中的GetTeam(id)函数 服务调用\u teamRepository.GetTeam(id) 存储库对Context.Team.First(
- 控制器调用
\u teamService.GetTeam(id)中的
函数代码>GetTeam(id)
- 服务调用
\u teamRepository.GetTeam(id)代码>
- 存储库对
执行LINQ调用,将团队实体模型返回给服务李>Context.Team.First(…)
- 服务获取模型并将其映射到返回控制器的DTO李>
- 控制器以JSON格式将其提供给应用程序
return new DTOObject {
team = _teamRepo.GetTeam(id),
competitions = _compRepo.GetCompsByTeam(id) <-- is a list
}
返回新的DTOObject{
团队=_teamRepo.GetTeam(id),
竞争=_compepo.GetCompsByTeam(id)我更喜欢从我的服务返回实体,而不是DTO。原因是,有时使用服务调用的结果创建ASP.NET MVC视图模型,有时使用DTO作为JSON返回。有时这些DTO的要求不同,服务器端视图模型可以看到不应该向客户端公开的内容。Yo您可以在服务层中创建DTO,但在大多数情况下,这只是另一个映射,您必须注意它的价值,这就是我直接从控制器中的实体创建DTO或ViewModels的原因
此外,存储库模式基本上是无用的。如果您更改了数据存储,它可能会很有用,但在实践中,这些类型的更改伴随着对业务逻辑的许多其他更改,因此您的大多数服务层都会被重写,因此价值会丢失。您的问题肯定会被解决,因为这是主观的,但这是唯一的问题我已经在网上看到了EF中正确实现的存储库模式——但是请考虑不要使用存储库模式,直接在服务层使用数据上下文。它将使您的生活变得更容易,并且对于99%的项目来说,存储库模式的价值几乎为0。您可以为其添加方便的方法和接口,这比将其包装在许多其他存储库后面要好。@DavidBrowne Microsoft Nope.DbContext是工作单元。DbSet是一个存储库。然而,DbSet仅在EF的意义上是一个存储库。如果您想使用另一种数据访问技术,它没有多大帮助存储库能够更改数据访问,但EF实现只允许您使用另一个EF实现来更改数据访问。如果您想更改存储过程的DataAccess,那么在使用数据库集时祝您好运。真正的存储库将允许您在不更改服务层的情况下更改数据访问。重点是如果您想要一个存储库很容易提供多个实现的y类型您可以通过DbContext实现的接口来实现这一点。使用不为每个实体公开IQueryable属性的存储库有一个基本的折衷,因为它迫使您在错误的组件中指定查询。我同意您的两个评论,我希望如此Microsoft在这方面会更明确。存储库模式只有在您可能正在更改数据访问时才有用。如果您不想更改ORM,请不要使用它。这不是一场可怕的噩梦,但它没有添加任何内容。很多人仍然使用它,但只是因为他们习惯在其他堆栈中使用它,或者是因为有人告诉他们这是非常愚蠢的,微软应该清楚地说出来。