using语句如何帮助防止ZombieCheck()

时间:2019-06-21 17:07:28

标签: c# using

当我的EF Core C#Web API中的一个API调用被快速击中时,出现此错误。

Proj> System.InvalidOperationException: This SqlTransaction has completed; it is no longer usable.
Proj>    at System.Data.SqlClient.SqlTransaction.ZombieCheck()

解决方案似乎是:

  1. 使用using语句c#corner link来处理连接
  2. 根据this SO postAddDbContext更改为AddDbContextPool

用于只读上下文的using语句如何帮助防止以下错误?似乎不叫new MyContext()

public class MyController : Controller
{
    private readonly MyContext _mc;

    public GreenCardController(MyContext mc){_mc=mc;}

    [HttpGet("GetCompanies")]
    public IEnumerable<vwCompany> GetCompanies(int lgid)
    {
        using (MeSeeksContext mc = _mc){
          return mc.myTable.Where(x=>x.id==lgid)
        }
     }

1 个答案:

答案 0 :(得分:0)

您可以通过控制器的构造函数从控制器外部接收数据库上下文。如果要使用该模式,请在完成后让外部调用方负责处理上下文。遵循该策略时,请勿使用using关键字。

您特别收到错误消息,因为返回的IEnumerable延迟评估(这意味着直到必要时才对其进行评估)。直到退出mc语句的范围后using被处置之后,调用代码才有机会迭代IEnumerable。

一种解决方案是让该方法实例化其自身的上下文并在返回之前具体化响应。当返回的对象总数很小时,此方法效果很好,可以通过在调用后添加.ToList()来实现。

using (MeSeeksContext mc = new MeSeeksContext() ){
    return mc.myTable.Where(x=>x.id==lgid).ToList();
}

如果返回大量项目,则可以正确地遵循从调用方接收控制器实例的方式(或者,可以将其分配为控制器的字段,并确保在控制器实例时将其处置被处置)。如果走那条路,请不要在方法中使用using语句。使用_mc

return _mc.myTable.Where(x=>x.id==lgid);