0

我使用 Subsonic 3.0.0.4(ActiveRecord 方法)已经有一段时间了,我最近编写了一个小页面,该页面基本上检索了给定年份的大约 500 条记录,然后我只是遍历它们中的每一个,创建Active Record 类,只需修改 Period 字段,并将每个实例保存在循环中。

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

代码如下:

if (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();
        }
    }

我做错了吗?在这一点上,我不确定这是否是 Subsonic 错误,或者我是否需要以某种方式手动关闭连接。

我在谷歌上搜索过关于使用亚音速时类似问题的帖子,但没有出现。我得到错误的通常原因是没有关闭 SqlDataReader,但老实说,我不相信 Subsonic 没有关闭它。我使用的是最新版本。

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

4

1 回答 1

2

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

我知道 Save() 会触发并关闭 ExecuteScalar() - 这不应该让连接保持打开状态。但是,如果您在该循环中获取相关记录 - 是的,这可能会出现问题。

所以 - 我建议使用某种探查器和调试器来单步执行你的循环 - 查看进行了哪些查询。

或者 - 这对于使用 BatchInsert 东西来说已经成熟了,它可以让所有东西都保持在一个漂亮、整洁的单连接事务中。

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

于 2012-07-20T18:03:00.370 回答