基于变量创建 DataReader

Creating a DataReader based on a variable

我正在尝试创建一个基于变量的 DataReader。我需要根据选择TreeView中的哪个节点来填充一系列TextBoxes,并且Parent节点数据与Child节点数据不同。所以,我写了这段代码:

using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["PBRConnectionString"].ConnectionString))
{
    try
    {
        conn.Open();
        if (TreeViewAccts.SelectedNode.Parent == null)
        {
            // At the parent level, we filter by Account Group ID
            SqlCommand cmd = new SqlCommand(@"Select [ACCT_GRP_PK], [ACCT_GRP], 'X' as [DOS], [ACTIVE_FLG], [LOAD_BY], [LOAD_TIMESTAMP], [UPDT_BY], [UPDT_TIMESTAMP], [A_FLG_UPDT_BY], [A_FLG_UPDT_TIMESTAMP] from [ACCT_GRP_LIST] where [ACCT_GRP_PK] = @AcctID ORDER BY [ACCT_GRP] ASC", conn);

            cmd.Parameters.AddWithValue("@AcctID", Convert.ToInt32(TreeViewAccts.SelectedValue.ToString()));
        }
        else
        {
            // At the child level, we filter by Account ID
            SqlCommand cmd = new SqlCommand(@"Select [ACCT_PK], [ACCT_NUM], [DOS], [ACTIVE_FLG], [LOAD_BY], [LOAD_TIMESTAMP], [UPDT_BY], [UPDT_TIMESTAMP], [A_FLG_UPDT_BY], [A_FLG_UPDT_TIMESTAMP] from [ACCT_LIST] where [ACCT_PK] = @AcctID ORDER BY [ACCT_NUM] ASC", conn);

            cmd.Parameters.AddWithValue("@AcctID", Convert.ToInt32(TreeViewAccts.SelectedValue.ToString()));
        }

        //Here is the trouble
        using (SqlDataReader reader = cmd.ExecuteReader())
        while (reader.Read())
        {
            txtID.Text = reader.GetByte(0).ToString();
            txtName.Text = reader.GetByte(1).ToString();
            txtDOS.Text = reader.GetByte(2).ToString();
            txtFlag.Text = reader.GetByte(3).ToString();
            txtLoadedBy.Text = reader.GetByte(4).ToString();
            txtLoadedOn.Text = reader.GetByte(5).ToString();
        }

问题是,在这一行:

using (SqlDataReader reader = cmd.ExecuteReader())

它告诉我

'cmd' doesn't exist in the current context.

我假设这是因为它在定义 cmdif/else 块之外。

我怎样才能完成这项工作?

您需要在 if 语句之外设置命令,否则该对象指针仅在该 if 块和 else 块中具有作用域。然后你可以在块中分配它。

using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["PBRConnectionString"].ConnectionString))
{
    try
    {
        conn.Open();
        SqlCommand cmd = null; // declare it here
        if (TreeViewAccts.SelectedNode.Parent == null)
        {
            // At the parent level, we filter by Account Group ID
            cmd = new SqlCommand(@"Select [ACCT_GRP_PK], [ACCT_GRP], 'X' as [DOS], [ACTIVE_FLG], [LOAD_BY], [LOAD_TIMESTAMP], [UPDT_BY], [UPDT_TIMESTAMP], [A_FLG_UPDT_BY], [A_FLG_UPDT_TIMESTAMP] from [ACCT_GRP_LIST] where [ACCT_GRP_PK] = @AcctID ORDER BY [ACCT_GRP] ASC", conn);

            cmd.Parameters.AddWithValue("@AcctID", Convert.ToInt32(TreeViewAccts.SelectedValue.ToString()));
        }
        else
        {
            // At the child level, we filter by Account ID
            cmd = new SqlCommand(@"Select [ACCT_PK], [ACCT_NUM], [DOS], [ACTIVE_FLG], [LOAD_BY], [LOAD_TIMESTAMP], [UPDT_BY], [UPDT_TIMESTAMP], [A_FLG_UPDT_BY], [A_FLG_UPDT_TIMESTAMP] from [ACCT_LIST] where [ACCT_PK] = @AcctID ORDER BY [ACCT_NUM] ASC", conn);

            cmd.Parameters.AddWithValue("@AcctID", Convert.ToInt32(TreeViewAccts.SelectedValue.ToString()));
        }

来自MSDN

If you declare a variable within a block construct such as an If statement, that variable's scope is only until the end of the block. The lifetime is until the procedure ends.

问题是您在 if-else 块的范围内定义 cmd 变量,因此在这些块之外不知道它。解决方案是在 if-else 块中声明 cmd。像这样:

try
{
    SqlCommand cmd = null;
    ....
    if (TreeViewAccts.SelectedNode.Parent == null)
    { 
        cmd = new SqlCommand(@"Select [ACCT_GRP_PK], [ACCT_GRP], 'X' as [DOS], [ACTIVE_FLG], [LOAD_BY], [LOAD_TIMESTAMP], [UPDT_BY], [UPDT_TIMESTAMP], [A_FLG_UPDT_BY], [A_FLG_UPDT_TIMESTAMP] from [ACCT_GRP_LIST] where [ACCT_GRP_PK] = @AcctID ORDER BY [ACCT_GRP] ASC", conn);
        ....
    }
    else
    {
         // At the child level, we filter by Account ID
         cmd = new SqlCommand(@"Select [ACCT_PK], [ACCT_NUM], [DOS], [ACTIVE_FLG], [LOAD_BY], [LOAD_TIMESTAMP], [UPDT_BY], [UPDT_TIMESTAMP], [A_FLG_UPDT_BY], [A_FLG_UPDT_TIMESTAMP] from [ACCT_LIST] where [ACCT_PK] = @AcctID ORDER BY [ACCT_NUM] ASC", conn);
         ....
    }
}