我想在一个事务中执行多个与身份相关的操作。一般而言,文档中有针对 EF 的一些指导,但没有特别针对 Identity 的指导。
我正在使用这种方法:
using var transaction = await _context.Database.BeginTransactionAsync();
try
{
var result1 = await _userManager.Foo();
if (!result1.Succeeded)
throw new Exception("Could not foo.");
var result2 = await _userManager.Bar();
if (!result2.Succeeded)
throw new Exception("Could not bar.");
await transaction.CommitAsync();
}
catch (Exception e)
{
_logger.LogError(e, "Something bad happened, but changes were rolled back.");
// ...handle error
}
如果执行进入 catch 块,则事务不会提交并被释放(从而自动回滚)。
我不明白的是
_context
是否与_userManager
内部使用的相同?我认为上下文默认注册为作用域(每个请求),因此我假设在 ASP.NET Core HTTP 请求中,Identity 和我的代码将使用相同的上下文。
这是正确的吗?我的代码是“正确的方式”还是可以改进?
您的理解是正确的。在 ASP.NET Core 中,默认行为是将
DbContext
注册为作用域,这意味着在同一个 HTTP 请求中,相同的上下文实例将在参与该请求作用域的所有组件之间共享,包括 _userManager
.
因此,在您的代码中,
_context
和 _userManager
通常会在同一个 HTTP 请求中共享 DbContext
的相同实例。因此,使用事务执行涉及 _context
和 _userManager
的多个操作应该可以按预期工作。
您的代码在使用事务在单个工作单元中执行多个与身份相关的操作方面看起来不错。但是,有几点需要考虑改进:
错误处理:您的错误处理方法很好,因为它确保如果任何操作失败,事务都会回滚。但是,抛出通用的
Exception
可能无法提供有关到底出了什么问题的足够信息。使用更具体的异常类型或提供有关错误的更多上下文是一个很好的做法。
异步/等待模式:您正确使用了异步/等待模式,这有利于 ASP.NET Core 应用程序的性能和可扩展性。
记录:您正在记录错误,这对于诊断问题很重要。但是,请确保记录足够的信息以便于故障排除。
依赖注入:确保
_userManager
和_context
已正确注册并注入到您的类中。看来你做得正确,但值得一提。
总体而言,您的方法对于在 ASP.NET Core 中的事务中执行多个与身份相关的操作似乎很可靠。只需确保有效处理错误并提供足够的日志记录和上下文以用于调试目的。