在 SqlDataReader while 循环中覆盖变量

Overwriting of variable in SqlDataReader while-loop

我已经阅读了一些似乎与此类似的主题,但找不到解决我的问题的方法,我没有经常使用堆栈溢出,所以请多多包涵

我有一个使用 SqlDataReader 的 while 循环,它从数据库中提取信息并将其放入开发请求列表中,如下所示

public ListOfDevelopmentRequestsModel GetDevRequests(List<SelectListItem> evaluators)
        {
            SqlCommand cmd = new SqlCommand(StoredProcedures.DevRequests.GetDevRequests, Conn);
            cmd.CommandType = CommandType.StoredProcedure;
            ListOfDevelopmentRequestsModel ListOfDevRequests = new ListOfDevelopmentRequestsModel();
            Conn.Open();
            SqlDataReader reader = cmd.ExecuteReader();

            while (reader.Read())
            {
                DateTime requestDate = Convert.ToDateTime(reader["DateCreated"].ToString());
                string requestorFirstName = reader["Staff First Name"].ToString();
                string requestorLastName = reader["Staff Last Name"].ToString();
                string requestorEmailAddress = reader["Staff Email"].ToString();
                string solutionName = reader["SolutionName"].ToString();
                string solutionDescription = reader["SoultionDescription"].ToString();
                string solutionElementName = reader["SolutionElementName"].ToString();
                string solutionElementDescription = reader["SolutionElementDescription"].ToString();
                string itemToChange = reader["ItemChange"].ToString();
                string changeDetails = reader["ChangeDetail"].ToString();

                List<SelectListItem> evaluatorList = new List<SelectListItem>(DisplayCurrentEvaluator(evaluators, evaluator));

                DevelopmentRequestModel DevRequest = new DevelopmentRequestModel
                {
                    RequestDate = requestDate,
                    RequestorName = $"{requestorFirstName} {requestorLastName}",
                    RequestorEmailAddress = requestorEmailAddress,
                    SolutionName = solutionName,
                    SolutionDescription = solutionDescription,
                    SolutionElementName = solutionElementName,
                    SolutionElementDescription = solutionElementDescription,
                    ItemToChange = itemToChange,
                    ChangeDetails = changeDetails,
                    AccordionHeading = $"{(changeID.PadLeft(4, '0'))} - {requestorFirstName} {requestorLastName} - {itemToChange}"
                };

                ListOfDevRequests.DevelopmentRequests.Add(DevRequest);
            }
            Conn.Close();

            return ListOfDevRequests;
        }

我还有一个获取请求评估者的列表

        public static List<SelectListItem> GetEvaluators()
        {
            List<SelectListItem> evaluators = new List<SelectListItem>();
            SqlCommand cmd = new SqlCommand(StoredProcedures.DevRequests.GetEvaluators, Conn);
            cmd.CommandType = CommandType.StoredProcedure;
            Conn.Open();
            SqlDataReader reader = cmd.ExecuteReader();
            while (reader.Read())
            {
                evaluators.Add(
                    new SelectListItem
                    {
                        Text = reader["Staff Name"].ToString(),
                        Value = reader["Staff Code"].ToString(),
                    });
            }
            Conn.Close();
            return evaluators;
        }

最后我有一个列表,它将传递上面的 Evaluators 列表和从数据库中提取的 Evaluator:string evaluator = reader["Evaluator"].ToString(); 并将根据是否设置 select 列表的默认值Evaluator 名称与 Text 值匹配,并将其设置为 selected select 列表项。

        public List<SelectListItem> DisplayCurrentEvaluator(List<SelectListItem> evaluators, string evaluator)
        {
            foreach (var item in evaluators)
            {
                if (item.Text == evaluator)
                {
                    item.Selected = true;
                }
                else
                {
                    item.Selected = false;
                }
            }

            return evaluators;

        }

问题是循环中的第一项有 Evaluator "Bill" 并且 "Bill" 是 selected,并且工作正常,但是循环中的第二项是 "John",当它将 "John" 设置为 selected 时,它会将 "Bill" 替换为第一项中的 selected 值 "John"

代码最终变得一团糟,因为我尝试了多种不同的修复方法,但我很困惑,希望得到帮助。

抱歉,如果 post 的格式不便于阅读,我可以尝试重新格式化并在需要时提供更多信息。

干杯

编辑代码:

GetDevRequests()

 public ListOfDevelopmentRequestsModel GetDevRequests(List<SelectListItem> evaluators)
        {
            SqlCommand cmd = new SqlCommand(StoredProcedures.DevRequests.GetDevRequests, Conn);
            cmd.CommandType = CommandType.StoredProcedure;
            ListOfDevelopmentRequestsModel ListOfDevRequests = new ListOfDevelopmentRequestsModel();
            Conn.Open();
            SqlDataReader reader = cmd.ExecuteReader();
            List<SelectListItem> evaluatorList = new List<SelectListItem>();

            while (reader.Read())
            {
                string changeID = reader["ChangeID"].ToString();
                string evaluator = reader["Evaluator"].ToString();
                string status = reader["Status"].ToString();
                string priority = reader["Priority"].ToString();
                string eliteID = reader["RequestorID"].ToString();
                DateTime requestDate = Convert.ToDateTime(reader["DateCreated"].ToString());
                string requestorFirstName = reader["Staff First Name"].ToString();
                string requestorLastName = reader["Staff Last Name"].ToString();
                string requestorEmailAddress = reader["Staff Email"].ToString();
                string solutionName = reader["SolutionName"].ToString();
                string solutionDescription = reader["SoultionDescription"].ToString();
                string solutionElementName = reader["SolutionElementName"].ToString();
                string solutionElementDescription = reader["SolutionElementDescription"].ToString();
                string itemToChange = reader["ItemChange"].ToString();
                string changeDetails = reader["ChangeDetail"].ToString();

                evaluatorList = DisplayCurrentEvaluator(evaluators, evaluator);

                DevelopmentRequestModel DevRequest = new DevelopmentRequestModel
                {
                    ChangeID = (changeID.PadLeft(4, '0')),
                    Evaluator = evaluator,
                    Evaluators = evaluatorList,
                    Status = status,
                    Priority = priority,
                    EliteID = eliteID,
                    RequestDate = requestDate,
                    RequestorName = $"{requestorFirstName} {requestorLastName}",
                    RequestorEmailAddress = requestorEmailAddress,
                    SolutionName = solutionName,
                    SolutionDescription = solutionDescription,
                    SolutionElementName = solutionElementName,
                    SolutionElementDescription = solutionElementDescription,
                    ItemToChange = itemToChange,
                    ChangeDetails = changeDetails,
                    AccordionHeading = $"{(changeID.PadLeft(4, '0'))} - {requestorFirstName} {requestorLastName} - {itemToChange}"
                };

                ListOfDevRequests.DevelopmentRequests.Add(DevRequest);
            }
            Conn.Close();

            return ListOfDevRequests;
        }

DisplayCurrentEvaluator()

        public List<SelectListItem> DisplayCurrentEvaluator(List<SelectListItem> selectListItems, string selectListDefaultItem)
        {
            foreach (var item in selectListItems)
            {
                item.Selected = item.Text == selectListDefaultItem;
            }

            return selectListItems;

        }

问题出在这一行:

List<SelectListItem> evaluatorList = new List<SelectListItem>(DisplayCurrentEvaluator(evaluators, evaluator));

首先,这也可以写成

List<SelectListItem> evaluatorList = DisplayCurrentEvaluator(evaluators, evaluator);

您的 DisplayCurrentEvaluator 已经 return 是一个正确的列表,因此无需将其复制到新列表中。

但这是次要问题,因为据我所知,您没有使用 evaluatorList。在那个 while 循环的每次迭代中,您都在创建一个新的循环(这可能不是您想要的),然后您就忘记了它。我也看不到 evaluator 的设置位置,但这可能在您未显示的代码中。

因此您需要在循环外生成一次此列表并将其保存(可能在 class 级字段或 属性 中)。

还有一个额外的提示,DisplayCurrentEvaluator 方法也可以写成

public List<SelectListItem> DisplayCurrentEvaluator(List<SelectListItem> evaluators, string evaluator)
{
    foreach (var item in evaluators)
    {
        item.Selected = item.Text == evaluator;
    }

    return evaluators;
}

EDIT 在显示设置 evaluator 并使用结果 evaluatorList

的代码之后

您的 DisplayCurrentEvaluator 更新原始评估者列表并 returns 它。这有效地导致每个 evaluatorList 指向同一个列表,最后更新获胜。因此,请确保您 return 一个新列表。

public List<SelectListItem> DisplayCurrentEvaluator(List<SelectListItem> evaluators, string evaluator)
{
    var result = new List<SelectListItem>(evaluators.Count);

    foreach (var item in evaluators)
    {
        result.Add(new SelectListItem { Text = item.Text, Value = item.Value, Selected= item.Text == evaluator};      
    }

    return result;
}

此外,在循环内(仅)声明 evaluatorList。

 var evaluatorList = DisplayCurrentEvaluator(evaluators, evaluator);