【问题标题】:Recursive loop missing the first value in c#递归循环缺少c#中的第一个值
【发布时间】:2012-01-03 21:47:59
【问题描述】:

我想得到一个值列表,得到一个值后,我传递该值并调用相同的方法。

如果结构是这样的

60
|
61
|
63
|
64

代码运行良好,并在我通过 60 时返回所有值。

但是当结构是这样的

    60 
   |  |
  61  63
   |
  62

所以这里 61 和 63 的父 id 是 60。

那么第一次执行后传入的Org id是63,因为61和63是同时读取的,63是最后读取的orgid,所以将63传给下一个循环,返回0,循环结束。因此没有使用 orgid 61 执行任何操作。因此错过了 62。我在这里犯了什么错误。当读取器在同一查询中读取 2 个值时,将传递读取的第二个值。我想传递查询中读取的所有值。

private DataSet BindGridView(int id, List<int> userids)
{
    string GetOrgIDs = "select OrganisationID from tbl_organisation where ParentID =@ParentID";
    MySqlParameter[] paramet = new MySqlParameter[1];
    paramet[0] = new MySqlParameter("@ParentID", MySqlDbType.Int32);
    paramet[0].Value = id;
    int Orgid = 0;
    MySqlDataReader reader = server.ExecuteReader(CommandType.Text, GetOrgIDs, paramet);
    while (reader.Read())
    {
        Orgid = Convert.ToInt32(reader["OrganisationID"]);
        userids.Add(Orgid);
    }
    reader.Close();
    if (Orgid != 0)
    {
        BindGridView(Orgid, userids);
    }
}

我从页面加载中调用方法

 List<int> OrgIDs = new List<int>();
                OrgIDs.Add(60);
                BindGridView(60, OrgIDs);

我正在使用 Mysql 数据库

【问题讨论】:

    标签: c# asp.net recursion recursive-query


    【解决方案1】:

    您的递归调用需要位于 while 循环中才能调用每个 Orgid,但这将导致多个同时读取连接到您的数据库以获取资源可能是一个问题。

    while (reader.Read())
    {
        Orgid = Convert.ToInt32(reader["OrganisationID"]);
        userids.Add(Orgid);
        if (Orgid != 0)
        {
            BindGridView(Orgid, userids);
        }
    }
    reader.Close();
    

    【讨论】:

    • 好的,这里如果通过了 60,首先它得到 61,然后将 61 传递给方法,我得到 62,但我不会错过 63,我也会得到 There is already a open DataReader与必须首先关闭的此连接相关联。错误
    【解决方案2】:

    您正在使用找到的最后一个 id 的父级递归。因此,您会忽略任何可能的早期值的子代。

    将您找到的值添加到该列表参数和(新)本地列表中。然后遍历该本地列表并在值 != 0 时递归。

    这样您就不会打开多个结果集。

    private DataSet BindGridView(int id, List<int> userids)
    {
        string GetOrgIDs = "select OrganisationID from tbl_organisation where ParentID =@ParentID";
        MySqlParameter[] paramet = new MySqlParameter[1];
        paramet[0] = new MySqlParameter("@ParentID", MySqlDbType.Int32);
        paramet[0].Value = id;
        List<int> children = new List<int>(); // new local list
        MySqlDataReader reader = server.ExecuteReader(CommandType.Text, GetOrgIDs, paramet);
        while (reader.Read())
        {
            int orgid = Convert.ToInt32(reader["OrganisationID"]);
            userids.Add(orgid);
            children.Add(orgid);  // also add to local list
        }
        reader.Close();
    
        foreach(int child in children)
        if (child != 0)
        {
            BindGridView(child, userids);
        }
    }
    

    【讨论】:

      【解决方案3】:

      这个循环可以运行 100 次。

      while (reader.Read())
      {
          Orgid = Convert.ToInt32(reader["OrganisationID"]);
          userids.Add(Orgid);
      }
      reader.Close();
      

      循环所有记录后,OrdId 只有最后一个值。

      if (Orgid != 0)
      {
          BindGridView(Orgid, userids);
      }
      

      BindGridView(Orgid, userids);仅在 reader.read() 循环中的最后一个 OrgId 上被调用。

      我认为它只会在 63 上调用 BindGridView(取决于数据顺序)并跳过 61 和之前的任何其他内容。

      【讨论】:

      • 对不起,我应该添加一些示例代码来更正。安迪和汉斯已经有其他一些很好的例子了。
      猜你喜欢
      • 2020-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-11
      • 2019-05-30
      • 2013-10-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多