2

クエリを単一のパラメータ化されたクエリクラスにカプセル化し始めています

では、パフォーマンスのセキュリティとその他の可能なすべての側面について、私のクラスを評価していただけますか?

何か提案はありますか ?

ここに私の選択したクラス

public static DataSet cmd_SelectQuery(string srCommandText, List<string> lstParameterNames, List<string> lstParameters)
{
    DataSet dsCmdPara = new DataSet();
    try
    {
        using (SqlConnection connection = new SqlConnection(DbConnection.srConnectionString))
        {
            using (SqlCommand cmd = new SqlCommand(srCommandText, connection))
            {
                cmd.CommandType = CommandType.Text;
                for (int i = 0; i < lstParameterNames.Count; i++)
                {
                    cmd.Parameters.AddWithValue(lstParameterNames[i], lstParameters[i]);
                }
                connection.Open();
                using (SqlDataAdapter sqlDa = new SqlDataAdapter(cmd))
                {
                    sqlDa.Fill(dsCmdPara);
                    return dsCmdPara;
                }
            }
        }
    }
    catch (Exception E)
    {
        csPublicFunctions.insertIntoTblSqlErrors(srCommandText + " " + E.Message.ToString());
    }
    return dsCmdPara;
}

そしてここに私の更新、削除クラス

public static void cmd_UpdateDeleteQuery(string srCommandText, List<string> lstParameterNames, List<string> lstParameters)
{
    try
    {
        using (SqlConnection connection = new SqlConnection(DbConnection.srConnectionString))
        {
            using (SqlCommand cmd = new SqlCommand(srCommandText, connection))
            {
                cmd.CommandType = CommandType.Text;
                for (int i = 0; i < lstParameterNames.Count; i++)
                {
                    cmd.Parameters.AddWithValue(lstParameterNames[i], lstParameters[i]);
                }
                connection.Open();
                cmd.ExecuteNonQuery();
            }
        }
    }
    catch (Exception E)
    {
        csPublicFunctions.insertIntoTblSqlErrors(srCommandText + " " + E.Message.ToString());
    }
}

答えてくれてありがとう

4

3 に答える 3

2

私はこれを電話で書いているので、2つの簡単な提案。

  1. 文字列ではなく、オブジェクトを取り込む
  2. パラメータリストとしてparamsobject[]を使用すると、メソッドの使用が少し自然になる可能性があります。
于 2012-12-24T21:14:36.100 に答える
1

コードは、現状では有効で正しいものです。フィードバックをお願いしましたので、以下の点があります。

(1)パラメータを作成するコードでは、データ型を指定することをお勧めします。

for (int i = 0; i < lstParameterNames.Count; i++)
{
    var parameter = cmd.Parameters.AddWithValue(lstParameterNames[i], lstParameters[i]);
    parameter.SqlDbType = SqlDbType.NVarChar; // or whatever type you need
}

(2) Fillメソッドが自動的に行うため、接続を明示的に開いたり閉じたりする必要はありません。

connection.Open();
using (SqlDataAdapter sqlDa = new SqlDataAdapter(cmd))
{
    sqlDa.Fill(dsCmdPara);
    connection.Close();
    return dsCmdPara;
}

(3)テーブルを1つだけにする場合は、DataSetの代わりにDataTableを使用します。より速く、より簡単になります。

(4)これはスタイルのポイントですが、接続を明示的に閉じると非常に役立ちます。クロージングに例外がある場合は、(pdbを介して)行番号を知っておくと非常に役立ちます。また、使用を忘れた場合に接続が漏れないようにするのに役立ちます。


編集

ポイント4を明確にしたいと思います。接続が閉じられたときに、クリーンアップによって例外が発生したと想定します。接続を明示的に閉じないと、Disposeメソッドで例外が発生し、他の多くの作業が行われる可能性があります。これにより、問題を引き起こすために私が何をしたかがわかりにくくなります。

この簡単な例を見てください。クリーンアップする必要のある基になるリソース(Disposeの理由全体)があり、例外がスローされます。

public class Resource: IDisposable
{
    public void Close()
    {
        CleanupMemory();
    }

    private void CleanupMemory()
    {
        throw new Exception();
    }

    public void Dispose()
    {
        CleanupMemory();
    }
}

2つの異なるアプローチの(クリーンアップされた)スタックトレースは次のとおりです。

using (var r = new Resource())
{
    r.Close();
}

   at ConsoleApplication1.Resource.CleanupMemory() in Program.cs:line 31
   at ConsoleApplication1.Resource.Close() in Program.cs:line 26
   at ConsoleApplication1.Program.Main(String[] args) Program.cs:line 16

using (var r = new Resource())
{

}


   at ConsoleApplication1.Resource.CleanupMemory() in Program.cs:line 35
   at ConsoleApplication1.Resource.Dispose() in Program.cs:line 40
   at ConsoleApplication1.Program.Main(String[] args) in Program.cs:line 18

最初の例では、Closeを呼び出すと例外が発生したことがわかっているので、デバッグを開始する場所があります。例外がスローされたことだけを知っている場合は、例外の情報に完全に依存する必要があります。他に文脈はありません。そして、ほとんどの例外メッセージは特に明確ではありません。:)

どちらも完全に正しいですが、まったく異なります。

エリック

于 2012-12-24T21:29:04.207 に答える
-1
public DataTable Get_DTable(String Query, Dictionary<String, String> Parameters)
    {
        try
        {
            using (con = new SqlConnection(cls_Connection.URL()))
            {
                if (con.State == 0)
                    con.Open();
                using (cmd = new SqlCommand(Query, con))
                {
                    foreach (KeyValuePair<string, string> item in Parameters)
                    {
                        cmd.Parameters.AddWithValue(item.Key, item.Value);
                    }

                    using (da = new SqlDataAdapter(cmd))
                    {
                        using (dt = new DataTable())
                        {
                            da.Fill(dt);
                            if (dt.Rows.Count > 0)
                            {
                                return dt;
                            }
                        }
                    }
                }
            }
        }
        catch (Exception exp)
        {
            MessageBox.Show(exp.Message,
                            "Information",
                            MessageBoxButtons.OK,
                            MessageBoxIcon.Information);
        }
        return null;
    }
于 2014-12-25T15:33:44.763 に答える