c# - 如何在 ASP.NET Core Web API 中管理 EFCore DbContext 生命周期?
问题描述
我正在实现 3 层架构,我的问题是:我应该在哪里打电话SaveChanges();
(如果适用)?我应该在哪里创建和提交事务?请阅读整个问题。
在下面的代码中,我只有“读取”操作,但您会了解架构的概念。我正在为这个决定而苦苦挣扎,但我提出了两个选择:
Core
在项目中引用 EFCore 。将 DbContext 注入到Service
类中,并通过方法将其注入到数据层。像这样:public class ItemService { private MyContext _ctx; private readonly IItemData _itemData; public ItemService(IItemData itemData) { _itemData = itemData; } public void InjectCtx(MyContext ctx) { _ctx = ctx; _itemData.InjectCtx(_ctx); } public void Operation(int itemId) { using (var transaction = _ctx.Database.BeginTransaction()) { //Do something _ctx.SaveChanges(); transaction.Commit(); } } }
Core
在工作单元对象中创建一个接口。其中将具有 SaveChanges 和 Transaction、Commit 方法。然后在数据层实现它们并在Service
类中相应地调用。
这是代码。我有3个项目:
- Infrstructure (Data) -参考 Core 和 EFCore
- 核心(业务逻辑)-无依赖
- Web API(MVC 项目)-参考 Core、Data 和 EFCore
- 核心(没有依赖关系,甚至没有对 EFCore 的引用):
public class ItemDto
{
public int ItemId { get; set; }
public string Name { get; set; }
}
public interface IItemData
{
Task<ItemDto> GetItem(int itemId);
}
public class ItemService
{
private readonly IItemData _itemData;
public ItemService(IItemData itemData)
{
_itemData = itemData;
}
public async Task<ItemDto> GetItem(int itemId)
{
return await _itemData.GetItem(itemId);
}
}
- 数据(参考 Core 项目和 EFCore)
public class ItemData : IItemData
{
private readonly MyContext _ctx;
public ItemData(MyContext ctx)
{
_ctx = ctx;
}
public async Task<ItemDto> GetItem(int itemId)
{
var item = await _ctx.Items
.Where(i => i.ItemId == itemId)
.Select(row => new ItemDto()
{
ItemId = row.ItemId,
Name = row.ItemName
})
.FirstOrDefaultAsync();
return item;
}
}
- 网络 API:
[Route("api/[controller]")]
[ApiController]
public class ItemsController : ControllerBase
{
private readonly ItemService _itemService;
public ItemsController(ItemService itemService)
{
_itemService = itemService;
}
[HttpGet("{itemId}")]
public async Task<ItemDto> Get(int itemId)
{
return await _itemService.GetItem(itemId);
}
}
解决方案
推荐阅读
- mysql - 选择未定义的行
- javascript - Firebase 实时数据库读取操作 - 只能返回部分文档吗?
- git - 配置 git 不使用“.gitignore”,而是使用“gitignore”
- python - 使用 PyDrive 将文件上传到 Google-drive Teamdrive 文件夹
- java - Springboot 不起作用,除非输入 hello
- cygwin - 在 Cygwin 上构建 opnMPI
- android - Android Studio 模拟器:进程以退出代码 3 结束
- c# - 将 wsdl 文件导入 C# WCF 项目,并公开 wsdl 合同
- javascript - 反应:在 Div 上设置 scrollTop 在特定情况下不起作用
- android - 如何在圆形 ProgessBar 内覆盖 imageView