0

私はしばらくの間Subsonic3.0.0.4(ActiveRecordアプローチ)を使用してきましたが、最近、基本的に特定の年の約500レコードを取得する小さなページをコーディングしました。次に、それぞれをループして、新しいインスタンスを作成します。 Active Recordクラス、Periodフィールドを変更し、ループ内の各インスタンスを保存するだけです。

問題は、そのページを実行した後、SQLサーバーで(sp_who2を見て)多くのSQL接続がハング/開いたままになることです。ページの実行が完了する前に、「タイムアウトが期限切れになりました。プールから接続を取得する前にタイムアウト期間が経過しました。これは、プールされたすべての接続が使用中であり、最大プールサイズに達したために発生した可能性があります。」エラー。

コードは次のとおりです。

if(string.IsNullOrEmpty(tbPeriodoAGenerar.Text))return;

    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がそれを閉じていないと信じています..そして私は最新バージョンを使用しています。

何か案は?どんな助けでも大歓迎です。

4

1 に答える 1

2

ORMベースのオブジェクトにループがあるときはいつでも、おそらくN+1の問題があることを考慮する必要があります。モデルが表示されませんが、ループ内でいくつかの追加のクエリを実行していることは間違いありません。

Save()がExecuteScalar()を起動して閉じることを知っています。これにより、接続が開いたままになることはありません。ただし、そのループ内で関連レコードをフェッチしている場合は、問題が発生する可能性があります。

したがって、ある種のプロファイラーとデバッガーを使用してループをステップスルーすることをお勧めします。どのクエリが実行されるかを確認してください。

あるいは、これは、すべてを適切で整然とした単一接続トランザクションに保つBatchInsertのものを使用するのに適しています。

詳細については、こちらをお読みください: http ://subsonic.wekeroad.com/docs/Linq_Inserts

于 2012-07-20T18:03:00.370 に答える