在实体框架核心上使用带有sqlserver的asp.net核心,我们有一个我们想要解决的休息api的端点。
在启动时,我们使用框架
注册DBContextservices.AddDbContext<DBContext>(options=>options.UseSqlServer(/*connection string*/));
我们的控制器方法就像
[HttpPost(/*route*/)]
public ObjectResult doWork([FromBody] string[] args)
{
IInjectedLogic.doWorkAsync(args);
return new OkObjectResult("");
}
我们的逻辑类就像
public interface IInjectedLogic
{
Task doWorkAsync(string[] args);
}
public class InjectedLogic:IInjectedLogic
{
private DBContext ctx;
private ILegacyWCFService wcfClient;
private ILogger logger;
public InjectedLogic(DBContext ctx,ILegacyWCFService wcfClient,ILogger logger)
{
this.ctx=ctx;
this.wcfClient=wcfClient;
this.logger=logger;
}
public async Task doWorkAsync(string[] args)
{
using(var transaction=ctx.Database.BeginTransaction())
{
try
{
string[] processed=await wcfClient.doOtherWorkAsync(args);
}
catch(Exception ex)
{
transaction.RollBack();
logger.logError(ex);
}
transaction.Commit();
}
}
}
问题是在调用begin transaction时始终处理ctx.Database
。我的预感是,一旦控制器完成并且返回的内容超出了范围,框架就会调用dispose。
有人可以证实我的怀疑或告诉我真正发生了什么,并且如果可能的话,还有一种方法可以解决这个问题,同时仍然保持着火灾并忘记建筑?
答案 0 :(得分:0)
您可以从DI容器创建新范围。您的依赖项的新实例将得到解决,并在完成时处理。
示例:
...
using Microsoft.Extensions.DependencyInjection;
...
[HttpPost(/*route*/)]
public IActionResult DoWork([FromBody] string[] args)
{
using (var scope = Request.HttpContext.RequestServices.CreateScope())
{
var worker = scope.ServiceProvider.GetService<IInjectedLogic>();
worker.doWorkAsync(args);
}
return NoContent();
}