我试图在基于ASP.NET Core 6的web应用程序(使用EF )中实现服务和存储库模式,但我认为我做了一些错误的事情。在我的控制器中,我注入了一个服务实例,然后可以像这样使用它来获取、创建、更新或删除实体:
[HttpPost]
public async Task<IActionResult> CreateProject([FromBody] Project body)
{
int projectId = await this.projectService.CreateProjectAsync(body);
return CreatedAtAction(nameof(GetProject), new { id = projectId }, null);
}然后,CreateProjectAsync函数执行验证(如果有必要),并调用ProjectRepository类的相应CreateProjectAsync函数。需要注意的一件重要事情是,Project类是由我自己创建的,它也用作视图模型。在数据库中创建/更新它之前,或者在从数据库中读取它之后,它被映射到存储库中相应的before类型(例如TblProject)。
这种方法在很多情况下都很好,但当我需要使用事务时,我经常会遇到问题。一个例子是,除了项目之外,我还想在创建新项目时同时创建相关实体。我只希望在项目和相关实体都已成功创建时,此操作才能成功,而我必须使用事务来完成此操作。但是,我的服务无法创建事务,因为它们不知道EF DbContext类,所以我现在唯一的选择是直接在存储库中创建事务。这样做会迫使我在同一个存储库中创建所有的东西,但是到目前为止,我看到的每个例子都表明,不要将不同的实体混合在一个存储库中。
在类似的项目中,这通常是如何做到的?我的架构有什么问题吗?我应该考虑改变这个项目,使我的生活更轻松吗?
发布于 2022-01-25 09:35:31
问得好!默认情况下,EF上下文被注册为一个作用域依赖项-因此每个请求一个。您可以创建一个简单的事务服务(注册为一个作用域依赖项),该服务将公开事务处理。可以根据需要将此服务注入您的存储库和其他服务层。
通过在事务开始时返回事务对象,您可以授予每个层相对于提交或回滚其自己的事务的自主权。
您还可以在事务服务的Dispose方法中添加一些清理逻辑,以便在释放服务时提交或回滚任何打开的事务。
为个人实践编辑:除了频繁的get操作之外,我已经放弃了几个项目的存储库模式。在服务层中直接使用EF上下文可以让我利用导航属性来执行复杂的多表插入或编辑。我还获得了执行这些操作的单次往返数据库以及隐式事务包装的额外好处。就个人而言,对于EF项目上的存储库模式来说,它变得越来越难了--除了您被真正锁定在EF之外,因为它遍布于底层服务层。
https://stackoverflow.com/questions/70846205
复制相似问题