0

我一直在使用Subsonic 3.0.0.4(ActiveRecord方法)一段时间,并且我最近编写了一个小页面,基本上可以检索给定年份的约500条记录,然后我只是循环遍历每个记录,创建新实例的Active Record类,只需修改Period字段,并将每个实例保存在循环中。Subsonic 3.0.0.4泄漏SQL连接?

问题是,执行该页面后,很多SQL连接在SQL服务器中被挂起/打开(通过查看sp_who2)。在页面执行完成之前,我得到“Timeout expired。在从池中获取连接之前已经超时的时间,可能是因为所有池中的连接都在使用中并且已达到最大池大小。错误。

的代码如下:

如果(string.IsNullOrEmpty(tbPeriodoAGenerar.Text))回报;

var idPeriodo = Convert.ToInt32(tbPeriodoAGenerar.Text); 



    var nuevaEncuesta = new Encuesta(); 

    nuevaEncuesta.IdPeriodo = idPeriodo; 
    nuevaEncuesta.IdResponsable = 1; 
    nuevaEncuesta.fechaCierre1 = Convert.ToDateTime(dpFechaCierre1.Value); 
    nuevaEncuesta.fechaCierre2 = Convert.ToDateTime(dpFechaCierre2.Value); 
    nuevaEncuesta.IdTipoEncuesta = (int)ETipoEncuesta.PorAnio; 
    nuevaEncuesta.nombreEncuesta = NombresEncuestas.COVA; 
    nuevaEncuesta.nombrePublico = NombresEncuestas.COVA_PUBLICO; 

    nuevaEncuesta.Save(); 


    var empresasActivas = Empresa.Find(x => x.activo == 1); 

    foreach (var empresa in empresasActivas) 
    { 
     EmpresaEncuesta ee = new EmpresaEncuesta(); 

     ee.IdEmpresa = empresa.IdEmpresa; 
     ee.IdEncuesta = nuevaEncuesta.IdEncuesta; 
     ee.IdEstatusContestado = (int)EEstatusEmpresaEncuesta.SinContestar; 
     ee.fechaMod = DateTime.Now; 
     ee.IdUsuario = 1; 
     ee.ipMod = IpUsuarioActual; 
     ee.Save(); 
    } 


    if (chkMigrarRespuestas.Checked) 
    { 


     var periodosAnteriores = new EncuestaBO().ObtenerPeriodosAnteriores(NombresEncuestas.COVA, idPeriodo); 
     int? periodoAnterior = null; 

     if (periodosAnteriores.Tables[0].Rows.Count > 0) 
     { 
      periodoAnterior = Convert.ToInt32(periodosAnteriores.Tables[0].Rows[0][Columnas.ID_PERIODO]); 
     } 

     if (!periodoAnterior.HasValue) return; 


     var respuestasCortoPlazo = COVACortoPlazo.Find(x => x.Periodo == (periodoAnterior)); 
     COVACortoPlazo ccp; 

     foreach (var ccpAnterior in respuestasCortoPlazo) 
     { 
      if (!empresasActivas.Where(emp => emp.IdEmpresa == ccpAnterior.IdEmpresa).Any()) continue; 

      ccp = new COVACortoPlazo(); 

      ccp.IdEmpresa = ccpAnterior.IdEmpresa; 
      ccp.CuentaCortoPlazo = ccpAnterior.CuentaCortoPlazo; 
      ccp.ComentariosAdicionales = ccpAnterior.ComentariosAdicionales; 
      ccp.RetiroVoluntarioOpcionId = ccpAnterior.RetiroVoluntarioOpcionId; 
      ccp.RetiroVoluntarioOtroDesc = ccpAnterior.RetiroVoluntarioOtroDesc; 
      ccp.RetiroEmpresaOpcionId = ccpAnterior.RetiroEmpresaOpcionId; 
      ccp.RetiroEmpresaOtroDesc = ccpAnterior.RetiroEmpresaOtroDesc; 

      ccp.Periodo = idPeriodo; 

      ccp.Save(); 
     } 



     var tablaCortoPlazoAnterior = COVATablaCortoPlazo.Find(x => x.Periodo == (periodoAnterior)); 
     COVATablaCortoPlazo ctcp; 

     foreach (var ctcpAnterior in tablaCortoPlazoAnterior) 
     { 
      if (!empresasActivas.Where(emp => emp.IdEmpresa == ctcpAnterior.IdEmpresa).Any()) continue; 

      ctcp = new COVATablaCortoPlazo(); 

      ctcp.IdEmpresa = ctcpAnterior.IdEmpresa; 
      ctcp.Periodo = idPeriodo; 

      ctcp.COVASegmentoOpcionId = ctcpAnterior.COVASegmentoOpcionId; 
      ctcp.NivelDinamicaMin = ctcpAnterior.NivelDinamicaMin; 
      ctcp.NivelDinamicaMax = ctcpAnterior.NivelDinamicaMax; 

      ctcp.NombreBono = ctcpAnterior.NombreBono; 
      ctcp.COVAPeriodicidadOpcionId = ctcpAnterior.COVAPeriodicidadOpcionId; 
      ctcp.MetodoCalculo = ctcpAnterior.MetodoCalculo; 
      ctcp.COVABaseCalculoOpcionId = ctcpAnterior.COVABaseCalculoOpcionId; 
      ctcp.RealAnualizado = ctcpAnterior.RealAnualizado; 

      ctcp.Save(); 
     } 



     var respuestasAnual = COVAAnual.Find(x => x.Periodo == (periodoAnterior)); 
     COVAAnual ca; 

     foreach (var caAnterior in respuestasAnual) 
     { 
      if (!empresasActivas.Where(emp => emp.IdEmpresa == caAnterior.IdEmpresa).Any()) continue; 

      ca = new COVAAnual(); 

      ca.IdEmpresa = caAnterior.IdEmpresa; 
      ca.CuentaAnual = caAnterior.CuentaAnual; 
      ca.NombreBono = caAnterior.NombreBono; 
      ca.FechaPago = caAnterior.FechaPago; 

      ca.ComentariosAdicionales = caAnterior.ComentariosAdicionales; 

      ca.RetiroVoluntarioOpcionId = caAnterior.RetiroVoluntarioOpcionId; 
      ca.RetiroVoluntarioOtroDesc = caAnterior.RetiroVoluntarioOtroDesc; 
      ca.RetiroEmpresaOpcionId = caAnterior.RetiroEmpresaOpcionId; 
      ca.RetiroEmpresaOtroDesc = caAnterior.RetiroEmpresaOtroDesc; 

      ca.Periodo = idPeriodo; 

      ca.Save(); 
     } 



     var tablaAnualAnterior = COVATablaAnual.Find(x => x.Periodo == (periodoAnterior)); 
     COVATablaAnual cta; 

     foreach (var ctaAnterior in tablaAnualAnterior) 
     { 
      if (!empresasActivas.Where(emp => emp.IdEmpresa == ctaAnterior.IdEmpresa).Any()) continue; 

      cta = new COVATablaAnual(); 

      cta.IdEmpresa = ctaAnterior.IdEmpresa; 
      cta.Periodo = idPeriodo; 

      cta.COVASegmentoOpcionId = ctaAnterior.COVASegmentoOpcionId; 
      cta.NivelDinamicaMin = ctaAnterior.NivelDinamicaMin; 
      cta.NivelDinamicaMax = ctaAnterior.NivelDinamicaMax; 

      cta.Minimo = ctaAnterior.Minimo; 
      cta.Target = ctaAnterior.Target; 
      cta.Maximo = ctaAnterior.Maximo; 

      cta.RealAnualPagado = ctaAnterior.RealAnualPagado; 
      cta.MetodoCalculo = ctaAnterior.MetodoCalculo; 
      cta.COVABaseCalculoOpcionId = ctaAnterior.COVABaseCalculoOpcionId; 

      cta.Save(); 
     } 



     var respuestasLargoPlazo = COVALargoPlazo.Find(x => x.Periodo == (periodoAnterior)); 
     COVALargoPlazo clp; 

     foreach (var clpAnterior in respuestasLargoPlazo) 
     { 
      if (!empresasActivas.Where(emp => emp.IdEmpresa == clpAnterior.IdEmpresa).Any()) continue; 

      clp = new COVALargoPlazo(); 

      clp.IdEmpresa = clpAnterior.IdEmpresa; 
      clp.CuentaLargoPlazo = clpAnterior.CuentaLargoPlazo; 
      clp.ComentariosAdicionales = clpAnterior.ComentariosAdicionales; 

      clp.RetiroVoluntarioOpcionId = clpAnterior.RetiroVoluntarioOpcionId; 
      clp.RetiroVoluntarioOtroDesc = clpAnterior.RetiroVoluntarioOtroDesc; 
      clp.RetiroEmpresaOpcionId = clpAnterior.RetiroEmpresaOpcionId; 
      clp.RetiroEmpresaOtroDesc = clpAnterior.RetiroEmpresaOtroDesc; 

      clp.PermiteCompraAcciones = clpAnterior.PermiteCompraAcciones; 

      clp.Periodo = idPeriodo; 

      clp.Save(); 
     } 



     var tablaLargoPlazoAnterior = COVATablaLargoPlazo.Find(x => x.Periodo == (periodoAnterior)); 
     COVATablaLargoPlazo ctlp; 

     foreach (var ctlpAnterior in tablaLargoPlazoAnterior) 
     { 
      if (!empresasActivas.Where(emp => emp.IdEmpresa == ctlpAnterior.IdEmpresa).Any()) continue; 

      ctlp = new COVATablaLargoPlazo(); 

      ctlp.IdEmpresa = ctlpAnterior.IdEmpresa; 
      ctlp.Periodo = idPeriodo; 

      ctlp.NombrePlan = ctlpAnterior.NombrePlan; 
      ctlp.COVATipoPlanOpcionId = ctlpAnterior.COVATipoPlanOpcionId; 


      ctlp.COVASegmentoOpcionId = ctlpAnterior.COVASegmentoOpcionId; 
      ctlp.NivelDinamicaMin = ctlpAnterior.NivelDinamicaMin; 
      ctlp.NivelDinamicaMax = ctlpAnterior.NivelDinamicaMax; 


      ctlp.RealPagadoFinalPlan = ctlpAnterior.RealPagadoFinalPlan; 
      ctlp.AniosEjerce = ctlpAnterior.AniosEjerce; 
      ctlp.MetodoCalculo = ctlpAnterior.MetodoCalculo; 
      ctlp.BaseCalculo = ctlpAnterior.BaseCalculo; 

      ctlp.Save(); 
     } 


     var respuestasVentas = COVAVentas.Find(x => x.Periodo == (periodoAnterior)); 
     COVAVentas cv; 

     foreach (var cvAnterior in respuestasVentas) 
     { 
      if (!empresasActivas.Where(emp => emp.IdEmpresa == cvAnterior.IdEmpresa).Any()) continue; 

      cv = new COVAVentas(); 

      cv.IdEmpresa = cvAnterior.IdEmpresa; 
      cv.CuentaVentas = cvAnterior.CuentaVentas; 
      cv.ComentariosAdicionales = cvAnterior.ComentariosAdicionales; 

      cv.RetiroVoluntarioOpcionId = cvAnterior.RetiroVoluntarioOpcionId; 
      cv.RetiroVoluntarioOtroDesc = cvAnterior.RetiroVoluntarioOtroDesc; 
      cv.RetiroEmpresaOpcionId = cvAnterior.RetiroEmpresaOpcionId; 
      cv.RetiroEmpresaOtroDesc = cvAnterior.RetiroEmpresaOtroDesc; 

      cv.Periodo = idPeriodo; 

      cv.Save(); 
     } 




     var tablaVentasAnterior = COVATablaVentas.Find(x => x.Periodo == (periodoAnterior)); 
     COVATablaVentas ctv; 

     foreach (var ctvAnterior in tablaVentasAnterior) 
     { 
      if (!empresasActivas.Where(emp => emp.IdEmpresa == ctvAnterior.IdEmpresa).Any()) continue; 

      ctv = new COVATablaVentas(); 

      ctv.IdEmpresa = ctvAnterior.IdEmpresa; 
      ctv.Periodo = idPeriodo; 

      ctv.COVASegmentoOpcionId = ctvAnterior.COVASegmentoOpcionId; 
      ctv.COVAPeriodicidadOpcionId = ctvAnterior.COVAPeriodicidadOpcionId; 

      ctv.Minimo = ctvAnterior.Minimo; 
      ctv.Target = ctvAnterior.Target; 
      ctv.Maximo = ctvAnterior.Maximo; 

      ctv.RealAnualizado = ctvAnterior.RealAnualizado; 
      ctv.MetodoCalculo = ctvAnterior.MetodoCalculo; 
      ctv.BaseCalculo = ctvAnterior.BaseCalculo; 

      ctv.Save(); 
     } 




     var respuestasGenerales = COVAGenerales.Find(x => x.Periodo == (periodoAnterior)); 
     COVAGenerales cg; 

     foreach (var cgAnterior in respuestasGenerales) 
     { 
      if (!empresasActivas.Where(emp => emp.IdEmpresa == cgAnterior.IdEmpresa).Any()) continue; 

      cg = new COVAGenerales(); 

      cg.IdEmpresa = cgAnterior.IdEmpresa; 

      cg.AccionesPorSituacionActual = cgAnterior.AccionesPorSituacionActual; 
      cg.ComentariosAccionesSituacionActual = cgAnterior.ComentariosAccionesSituacionActual; 
      cg.TomaCuentaSituacionDefinicionObjetivos = cgAnterior.TomaCuentaSituacionDefinicionObjetivos; 


      cg.Periodo = idPeriodo; 

      cg.Save(); 
     } 
    } 

我做错了吗?在这一点上,我不确定这是一个亚音速错误还是我需要手动关闭连接。

我已经搜索了使用亚音速时类似问题的帖子,但都没有出现。我得到的错误的通常原因是不关闭SqlDataReader,但我真的不相信Subsonic不关闭它..并且使用最新版本。

任何想法?任何帮助是极大的赞赏。

+0

需要看到实际的代码 - 否则无法接听。 – 2012-07-20 17:49:57

+0

让我得到它Rob..appreciated – GR7 2012-07-20 17:50:43

回答

2

任何时候当你在基于ORM的对象上有一个循环时,你必须考虑可能存在N + 1问题。我看不到你的模型,但我敢打赌,在你的循环中,你正在执行一些额外的查询。

我知道Save()会触发并关闭一个ExecuteScalar() - 这不应该让连接处于打开状态。但是,如果您在该循环内获取相关记录 - 是的,那可能会有问题。

所以 - 我会推荐使用某种类型的探查器和调试器来遍历你的循环 - 看看有什么查询。

另外 - 这是成熟的使用BatchInsert东西,这将保持一切都在一个很好,整洁的单连接事务。

这里阅读更多: http://subsonic.wekeroad.com/docs/Linq_Inserts

+0

感谢罗布。我实际上将在本周末将Subsonic源码添加到我的项目中,并尝试对此进行调试,但是我会首先检查Profiler。 关于循环中的其他查询,我不相信我正在做任何。这是实际的完整代码,我的对象没有任何可能触发任何其他查询的复杂或惰性加载属性。 我一定会看看BatchInsert。 再次感谢您的时间。一旦我解决了这个问题,我将确保在这里发布解决方案。 – GR7 2012-07-20 18:06:55

+0

使用Subsonic的BatchInsert处理泄漏的连接。 – GR7 2012-07-21 21:47:59