You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

EF Core异步调用ToListAsync遇数据库连接关闭错误求助

问题:异步执行IQueryable转List时出现数据库连接关闭错误

我从仓储层获取了三个IQueryable查询,在应用层用异步方式转换为List时,报错:

"BeginExecuteReader requires an open and available Connection. The connection's current state is closed."

由于性能要求必须用异步执行,需要解决这个问题。

应用层异步代码

private async Task<Tuple<List<GetCustomerDto>, List<GetSarfaslDto>, List<GetCusTellDto>>> getQuery()
{
    try
    {
        var customersTask =await _customerRepository.GetCustomers().ToListAsync().ConfigureAwait(false);

        var sarfaslsTask = await _customerRepository.GetCustomerSarfasl().ToListAsync().ConfigureAwait(false);

        var cusTellsTask = await _cusTellRepository.GetCusTell().ToListAsync().ConfigureAwait(false);

        return new Tuple<
            List<GetCustomerDto>,
            List<GetSarfaslDto>,
            List<GetCusTellDto>>( customersTask,  sarfaslsTask,  cusTellsTask);
    }
    catch (Exception ex)
    {
        throw;
    }
}

仓储层查询代码

public class CustomerRepository : ICustomerRepository
{
    #region Feilds
    private readonly HolooDatabaseContext _context;

    #endregion

    public CustomerRepository(HolooDatabaseContext context)
    {
        _context = context;
    }

    public IQueryable<GetSarfaslDto> GetCustomerSarfasl()
    {
        var query = (from customer in _context.CUSTOMER
                     join sarfasl in _context.SARFASL on customer.C_Code.Substring(RepositoryConstants.C_CODE) equals sarfasl.Sarfasl_Code.Substring(RepositoryConstants.SARFASL_C_CODE)
                     where sarfasl.Col_Code.Equals(RepositoryConstants.SARFASL_CODE)
                     select new GetSarfaslDto()
                     {
                         Sarfasl_Name = sarfasl.Sarfasl_Name,
                         Common = sarfasl.Common,
                         Col_Code = sarfasl.Col_Code,
                         Moien_Code = sarfasl.Moien_Code,
                         Tafzili_Code = sarfasl.Tafzili_Code,
                         Sarfasl_Code = sarfasl.Sarfasl_Code,
                         Group = sarfasl.Group,
                         Mahiat = sarfasl.Mahiat,
                         Can_Delete = sarfasl.Can_Delete,
                         Parent = sarfasl.Parent,
                         Type = sarfasl.Type,
                         ArzId = sarfasl.ArzId,
                         AutoUse = sarfasl.AutoUse,
                         DefaultSarfasl_Code = sarfasl.DefaultSarfasl_Code,
                         Delete = sarfasl.Delete,
                         ID = sarfasl.ID,
                         Mandeh = sarfasl.Mandeh,
                         MHaz_Code = sarfasl.MHaz_Code,
                         Money_Price = sarfasl.Money_Price,
                         OldType = sarfasl.OldType,
                         Sarfasl_Codeold = sarfasl.Sarfasl_Codeold,
                         Selected = sarfasl.Selected,
                         SParent = sarfasl.SParent,
                     }).AsQueryable();

        return query;
    }

    public IQueryable<GetCustomerDto> GetCustomers()
    {
        var query = (from customer in _context.CUSTOMER
                     join bedBesView in _context.W0_Calc_BedBes_UseInView on customer.C_Code equals bedBesView.CCode into bdc
                     from bd in bdc.DefaultIfEmpty()

                     let ff = _context.FACTURE.DefaultIfEmpty()
                         .FirstOrDefault(f => f.C_Code == customer.C_Code && f.Fac_Type == RepositoryConstants.FAC_TYPE_F)

                     let fk = _context.FACTURE.DefaultIfEmpty()
                         .FirstOrDefault(f => f.C_Code == customer.C_Code && f.Fac_Type == RepositoryConstants.FAC_TYPE_K)

                     let vastehCount = _context.CustomerVaseteh.Count(c => c.C_Code == customer.C_Code)

                     select new GetCustomerDto()
                     {
                         C_Code = customer.C_Code,
                         C_Code_C = customer.C_Code_C,
                         C_Name = customer.C_Name,
                         Kharid = customer.Kharid,
                         Forosh = customer.Forosh,
                         Vaseteh = customer.Vaseteh,
                         Vaseteh_Porsant = customer.Vaseteh_Porsant,
                         Karshenas = customer.Karshenas,
                         InListSiah = customer.InListSiah,
                         SelectType = customer.SelectType,
                         City_Code = customer.City_Code,
                         First_BalanceSanad = customer.First_BalanceSanad,
                         Sum_Takhfif = customer.Sum_Takhfif,
                         Etebar = customer.Etebar,
                         NetHlp = customer.NetHlp,
                         Col_Code_Bed = customer.Col_Code_Bed,
                         Moien_Code_Bed = customer.Moien_Code_Bed,
                         ArzID = customer.ArzID,
                         money_price = customer.money_price,
                         CalledDate = customer.CalledDate,
                         Creation_Date = customer.Creation_Date,
                         National_Code = customer.National_Code,
                         Economic_Code = customer.Economic_Code,
                         C_Tel = customer.C_Tel,
                         C_Mobile = customer.C_Mobile,
                         C_Fax = customer.C_Fax,
                         Cust_City = customer.Cust_City,
                         Cust_Ostan = customer.Cust_Ostan,
                         Cust_Mantagheh = customer.Cust_Mantagheh,
                         Zip_Code = customer.Zip_Code,
                         C_Address = customer.C_Address,
                         Email_Address = customer.Email_Address,
                         WebId = customer.WebId,
                         C_type = customer.C_type,
                         IsSeller = customer.IsSeller,
                         Cust_type = customer.Cust_type,
                         Agent = customer.Agent,
                         Agent_Porsant = customer.Agent_Porsant,
                         Anbardar = customer.Anbardar,
                         Arayeshgar = customer.Arayeshgar,
                         Arayesh_Porsant = customer.Arayesh_Porsant,
                         Arz_Mandeh = customer.Arz_Mandeh,
                         AwardCustomer = customer.AwardCustomer,
                         Birth_Date = customer.Birth_Date,
                         CAlarmEtebarCheck = customer.CAlarmEtebarCheck,
                         Car_Id = customer.Car_Id,
                         CheckReciveOfEtebar = customer.CheckReciveOfEtebar,
                         Choice = customer.Choice,
                         CityCodeLevy = customer.CityCodeLevy,
                         Cobbler = customer.Cobbler,
                         Col_Code_Bes = customer.Col_Code_Bes,
                         Comment = customer.Comment,
                         Companey_Code_F = customer.Companey_Code_F,
                         CoName = customer.CoName,
                         ContactDate = customer.ContactDate,
                         Counective_Name = customer.Counective_Name,
                         Counective_Tel = customer.Counective_Tel,
                         Cust_Job = customer.Cust_Job,
                         Cutter = customer.Cutter,
                         C_AliasName = customer.C_AliasName,
                         C_Code_C2 = customer.C_Code_C2,
                         DarsadAmuzeshP = customer.DarsadAmuzeshP,
                         DarsadEconomicCode = customer.DarsadEconomicCode,
                         DarsadShahrdari = customer.DarsadShahrdari,
                         Delete = customer.Delete,
                         DressType = customer.DressType,
                         Driver = customer.Driver,
                         Endeditdate = customer.Endeditdate,
                         Etebargerami = customer.Etebargerami,
                         ExporterSId = customer.ExporterSId,
                         FactOutOfEtebar = customer.FactOutOfEtebar,
                         First_BalanceSanad_Bes = customer.First_BalanceSanad_Bes,
                         Gender = customer.Gender,
                         GroupId = customer.GroupId,
                         HkharidarType1code = customer.HkharidarType1code,
                         HlpAman = customer.HlpAman,
                         Zone = customer.Zone,
                         isAbkar = customer.isAbkar,
                         isAbKonandeh = customer.isAbKonandeh,
                         IsActive = customer.IsActive,
                         isBonakdar = customer.isBonakdar,
                         IsChange = customer.IsChange,
                         IsCMS = customer.IsCMS,
                         isFactory = customer.isFactory,
                         isGoldmaker = customer.isGoldmaker,
                         isHamkar = customer.isHamkar,
                         iskifi = customer.iskifi,
                         isMekhrajiKargah = customer.isMekhrajiKargah,
                         isOtherCust = customer.isOtherCust,
                         isReygir = customer.isReygir,
                         isReygirKargah = customer.isReygirKargah,
                         isShopper = customer.isShopper,
                         isTamirKar = customer.isTamirKar,
                         JavaherSaz = customer.JavaherSaz,
                         KarPorsant = customer.KarPorsant,
                         KarPorsantDarsad = customer.KarPorsant,
                         KarPorsantType = customer.KarPorsantType,
                         latitude = customer.latitude,
                         longitude = customer.longitude,
                         Mandehgold750 = customer.Mandehgold750,
                         MandehPelatin = customer.MandehPelatin,
                         Mekhrajkar = customer.Mekhrajkar,
                         Mercer = customer.Mercer,
                         ModifyDate = customer.ModifyDate,
                         MohlatTasvieh = customer.MohlatTasvieh,
                         Moien_Code_Bes = customer.Moien_Code_Bes,
                         National_Code_F = customer.National_Code_F,
                         Notionality = customer.Notionality,
                         OstanCodeLevy = customer.OstanCodeLevy,
                         PelakChar = customer.PelakChar,
                         PelakCity = customer.PelakCity,
                         Pelakcitycode = customer.Pelakcitycode,
                         Pelakcode2 = customer.Pelakcode2,
                         Pelakcode3 = customer.Pelakcode3,
                         Personal_Code_F = customer.Personal_Code_F,
                         Personel = customer.Personel,
                         Porsant = customer.Porsant,
                         Porsant2 = customer.Porsant2,
                         PriceHamkar = customer.PriceHamkar,
                         Res_cust = customer.Res_cust,
                         SanadOutOfEtebar = customer.SanadOutOfEtebar,
                         SarFasl_Amani_Dar = customer.SarFasl_Amani_Dar,
                         SarFasl_Amani_Par = customer.SarFasl_Amani_Par,
                         SenfId = customer.SenfId,
                         SMSGroup = customer.SMSGroup,
                         Tafzili_Code_Bed = customer.Tafzili_Code_Bed,
                         Tafzili_Code_Bes = customer.Tafzili_Code_Bes,
                         Tailor = customer.Tailor,
                         TasviehType = customer.TasviehType,
                         TimeEndCustArayesh = customer.TimeEndCustArayesh,
                         TimeStartCustArayesh = customer.TimeStartCustArayesh,
                         UserCodeCust = customer.UserCodeCust,
                         Vaseteh_Code = customer.Vaseteh_Code,
                         Vaseteh_Porsant_C = customer.Vaseteh_Porsant_C,
                     }).AsQueryable();

        return query;
    }
}

解决方案

1. 并行执行异步任务,避免连接被释放

当前代码串行await每个任务,前一个任务执行完后DbContext可能释放连接,导致后续任务出错。应先启动所有异步任务,再统一等待完成:

private async Task<Tuple<List<GetCustomerDto>, List<GetSarfaslDto>, List<GetCusTellDto>>> getQuery()
{
    try
    {
        // 先启动所有异步任务,不立即await
        var customersTask = _customerRepository.GetCustomers().ToListAsync().ConfigureAwait(false);
        var sarfaslsTask = _customerRepository.GetCustomerSarfasl().ToListAsync().ConfigureAwait(false);
        var cusTellsTask = _cusTellRepository.GetCusTell().ToListAsync().ConfigureAwait(false);

        // 等待所有任务完成
        await Task.WhenAll(customersTask, sarfaslsTask, cusTellsTask).ConfigureAwait(false);

        return new Tuple<
            List<GetCustomerDto>,
            List<GetSarfaslDto>,
            List<GetCusTellDto>>(await customersTask, await sarfaslsTask, await cusTellsTask);
    }
    catch (Exception ex)
    {
        throw;
    }
}

2. 确保DbContext生命周期正确

如果DbContext是请求范围(如ASP.NET Core默认Scoped),需保证异步任务执行期间DbContext未被提前释放。检查依赖注入配置,确保仓储和DbContext生命周期匹配(均设为Scoped)。

3. 优化仓储层查询,避免N+1问题

GetCustomers中的FirstOrDefault会触发N+1查询,加剧连接压力。可改为左连接或投影子查询,合并逻辑到主查询:

// 优化FirstOrDefault逻辑,改为单次查询内的子查询
let ff = (from f in _context.FACTURE
          where f.C_Code == customer.C_Code && f.Fac_Type == RepositoryConstants.FAC_TYPE_F
          select f).FirstOrDefault()

4. 显式管理连接(备选方案)

若以上方法无效,可在执行查询前显式打开连接,完成后关闭:

private async Task<Tuple<List<GetCustomerDto>, List<GetSarfaslDto>, List<GetCusTellDto>>> getQuery()
{
    try
    {
        await _context.Database.OpenConnectionAsync().ConfigureAwait(false);
        
        var customersTask = await _customerRepository.GetCustomers().ToListAsync().ConfigureAwait(false);
        var sarfaslsTask = await _customerRepository.GetCustomerSarfasl().ToListAsync().ConfigureAwait(false);
        var cusTellsTask = await _cusTellRepository.GetCusTell().ToListAsync().ConfigureAwait(false);
        
        _context.Database.CloseConnection();
        
        return new Tuple<
            List<GetCustomerDto>,
            List<GetSarfaslDto>,
            List<GetCusTellDto>>(customersTask, sarfaslsTask, cusTellsTask);
    }
    catch (Exception ex)
    {
        _context.Database.CloseConnection();
        throw;
    }
}

注意:此方法需确保连接正确关闭,避免泄漏,优先推荐前三种方案。


内容的提问来源于stack exchange,提问作者shirin monzavi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 08:15:56