0

データベースから単一または複数のレコードを取得できる静的クラスにデータ リーダーがあります。これは、ASP.net アプリケーションで使用されます。しかし、最近奇妙な問題が発生しており、現在のメソッド構造が問題の原因ではないかと考えています。ときどき、データ リーダーがまだ開いているというエラーが表示されます。それ以外の場合は、サーバー タイムアウトが発生します。

これは、データベースからデータを取得する静的クラスの 1 つの例です。簡潔にするために、この例のメソッドの量を "get" 構造に減らしました。したがって、Reference 型の List を返したい場合は、次のフォームを aspx.cs ファイルと呼びます。

List<Reference> ref = ReferenceAdapter.GetAllByType(......);

どんな洞察も大歓迎です。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using DbProvider;
using MyBusinessModelLayer;

namespace MyDataAccessLayer
{
    public static class ReferenceAdapter //: IReferenceAdapter
    {
    static IDbProvider _dbProvider;

    static ReferenceAdapter()
    {
        Initialize();
    }

    private static void Initialize()
    {
        _dbProvider = new SqlDbProvider(Config.SqlConnectionString);
    }

    public static List<Reference> GetAllByType(ReferenceType referenceType)
    {
        return GetAllByType(referenceType, false);
    }

    public static List<Reference> GetAllByType(ReferenceType referenceType, bool isIncludeDeleted)
    {
        Hashtable hIn, hOut;
        string sp;

        sp = "[ReferenceSelectAllByReferenceType]";

        hIn = new Hashtable();
        hIn.Add("@ReferenceType", referenceType.ToString());
        if (!isIncludeDeleted)
        {
            hIn.Add("@Deleted", false);
        }

        hOut = new Hashtable();
        hOut.Add("@RTNStatus", 0);

        return GetMultipleFromDb(sp, hIn, hOut, CommandType.StoredProcedure);
    }

       private static List<Reference> GetMultipleFromDb(string sSql, Hashtable hInputParameters)
    {
        return GetMultipleFromDb(sSql, hInputParameters, new Hashtable(), new CommandType());
    }

    private static List<Reference> GetMultipleFromDb(string sSql, Hashtable hInputParameters, CommandType cType)
    {
        return GetMultipleFromDb(sSql, hInputParameters, new Hashtable(), cType);
    }

    private static List<Reference> GetMultipleFromDb(string sSql, Hashtable hInputParameters, Hashtable hOutputParameters, CommandType cType)
    {
        IDbCommand dbCommand = _dbProvider.Select(sSql, hInputParameters, hOutputParameters, cType);
        var lo = new List<Reference>();

        using (IDataReader dr = dbCommand.ExecuteReader())
        {
            while (dr.Read())
                lo.Add(GetObjectFromDataRecord(dr));
        }
        dbCommand.Connection.Close();
        return lo;
    }// GetMultipleFromDb()

    private static Hashtable GetParametersFromObject(Reference o)
    {
        Hashtable h = new Hashtable();
        h.Add("@ReferenceShortName", o.ShortName);
        h.Add("@ReferenceLongName", o.LongName);
        h.Add("@ReferenceDescription", o.Description);
        h.Add("@ReferenceType", o.Type.ToString());
        h.Add("@ReferenceSortKey", o.SortKey);

        return h;
    }// GetParametersFromObject()

    private static Reference GetObjectFromDataRecord(IDataRecord dr)
    {
        Reference o = new Reference();

        o.ReferenceId = dr["ReferenceID"].DBNullToInt();
        o.ShortName = dr["ReferenceShortName"].ToString();
        o.LongName = dr["ReferenceLongName"].ToString();
        o.Description = dr["ReferenceDescription"].ToString();
        o.Type = (ReferenceType)Enum.Parse(typeof(ReferenceType), dr["ReferenceType"].ToString(), true);
        o.SortKey = dr["ReferenceSortKey"].DBNullToInt();
        o.Created = dr["CreatedDate"].DBNullToDateMinVal();
        o.CreatedBy = dr["CreatedBy"].DBNullToInt();
        o.Updated = dr["UpdatedDate"].DBNullToDateMinVal();
        o.UpdatedBy = dr["UpdatedBy"].DBNullToInt();
        o.Deleted = Convert.ToBoolean(dr["Deleted"]);
        o.Deletable = GetAssetReferenceCount(o.Type, o.ReferenceId);

        return o;
    }// GetObjectFromDataRecord()
}

}

4

1 に答える 1

1

静的な共有オブジェクトがないようにコードを書き直してください。ほとんどの場合、サイトを使用するユーザーが増えるにつれて、静的メソッドが静的リソースを再利用するために同時実行性の問題が発生します。

それ以外の

List<Reference> ref = ReferenceAdapter.GetAllByType(......);

あなたが持つことができた

using ( var adapter = new ReferenceAdapter() )
{
   List<Reference> ref = adapter.GetAllByType();
}

同時実行の問題がないように新しいインスタンスが作成されるだけでなく、リソースが適切に破棄されるようにすることもできます。

独自のデータ アクセス レイヤーを記述して物事を再発明することは、従うべき正しい方法であると確信していますか? あなたの経験不足を考えると、既存のフレームワーク (orm や micro-orm など) を使用する方がはるかに安全な選択のように思えます。人々は同様の問題に歯を食いしばり、あなたより何年も先を行っており、すぐに使えるライブラリを設計することで経験を共有しています。

于 2013-09-05T18:25:09.403 に答える