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

自从我在手机上写这篇文章以来,有两个快速建议。

  1. 接收对象,而不是字符串
  2. 将 params object[] 作为参数列表可能会使您的方法更自然地使用。
于 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)如果您只打算拥有一个表,请使用 DataTable 而不是 DataSet。它将更快,更简单。

(4)这更像是一个风格点,但我发现明确关闭您的连接非常有帮助。如果关闭时出现异常,则具有行号(通过 pdb)非常有帮助。此外,它有助于确保您在忘记使用时不会泄漏连接。


编辑

我想澄清第 4 点。假设当连接关闭时,清理导致异常。如果您没有显式关闭连接,则会在 Dispose 方法中引发异常,这可能会做很多其他工作。这使得更难看出做了什么导致问题。

举这个简单的例子。有一个底层资源需要清理(Dispose 的全部原因),它会引发异常。

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

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

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

两种不同方法的(清理后的)堆栈跟踪是:

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 回答