引用计数生成不计算所有引用(循环困难)

本文关键字:引用 循环 计算所 | 更新日期: 2023-09-27 18:04:42

我目前正面临一个问题,我的while循环。这是一个场景,我需要分别生成金字塔左边和右边的总人数。下面是我的代码:

void GetLeftCount()
{
    string TOP = Session["UserID"].ToString();
    Connection.Open();
    SqlCommand CMD = new SqlCommand();
    CMD.Connection = Connection;
    CMD.CommandText = "SELECT * FROM Accounts WHERE AssignedTo=@Referrer AND PyramidPosition=@Position";
    CMD.Parameters.AddWithValue("@Referrer", TOP);
    CMD.Parameters.AddWithValue("@Position", "Left");
    SqlDataReader RDR = CMD.ExecuteReader();
    while (RDR.Read())
    {
        TOP = RDR["AccountID"].ToString();
        SqlCommand CMD2 = new SqlCommand();
        CMD2.Connection = Connection;
        CMD2.CommandText = "SELECT * FROM Accounts WHERE AssignedTo=@Referrer";
        CMD2.Parameters.AddWithValue("@Referrer", TOP);
        SqlDataReader RDR2 = CMD2.ExecuteReader();
        while(RDR2.Read())
        {
            string TOP2 = RDR2["AccountID"].ToString();
            SqlCommand CMD3 = new SqlCommand();
            CMD3.Connection = Connection;
            CMD3.CommandText = "SELECT * FROM Accounts WHERE AssignedTo=@Referrer";
            CMD3.Parameters.AddWithValue("@Referrer", TOP2);
            SqlDataReader RDR3 = CMD3.ExecuteReader();
            while(RDR3.Read())
            {
                LeftCount = LeftCount + 1;
            }
            LeftCount = LeftCount + 1;
        }
        LeftCount = LeftCount + 1;
    }
    Connection.Close();
}

我现在的问题是,金字塔下的推荐计数只达到一个特定的级别/层,即第3级。它不包括4级以下的转介等等。

我的循环出了什么问题?我应该把while循环转换成for循环吗?因为我不知道如何在不弄乱代码的情况下做到这一点。

注意:这是一个金字塔推荐投影,所有的评论和建议都是赞赏的。

引用计数生成不计算所有引用(循环困难)

您可以尝试以下方法之一。不用说,在任何情况下,您都需要在assigndto列上创建索引。

(1)使用递归函数计算任何深度的间接引用。不过,我要谨慎使用它,因为太多嵌套调用可能会使数据库陷入瓶颈。

int CountReferrers(string accountID, string position = null)
{
  int count = 0;
  // If a position argument was specified, add the filter to the query
  string cmdText = "SELECT * FROM Accounts WHERE AssignedTo=@Referrer";
  if (position != null)
    cmdText += " AND PyramidPosition=@Position";
  var cmd = new SqlCommand(cmdText, this.Connection);
  cmd.Parameters.AddWithValue("@Referrer", accountID);
  // If a position argument was specified, add the value to the parameter
  if (position != null)
    cmd.Parameters.AddWithValue("@Position", position);
  // Count the child referrers, without specifying position
  using (SqlDataReader reader = cmd.ExecuteReader())
  {
    while (reader.Read())
      count += CountReferrers(reader["AccountID"].ToString());
  }
  return count;
}
void Main()
{
  string userId = Session["UserID"].ToString();
  int referrerCount = CountReferrers(userId, "Left");
  Console.Write(referrerCount);
}

(2)编写一个更好的SQL查询,使用join将所有内容平铺到单个命令中。您可以添加任意数量的连接,最多8个,如果在此级别上没有引用,则AccountID8列将为NULL。

SELECT
    a1.AccountID AS AccountID1,
    a2.AccountID AS AccountID2,
    a3.AccountID AS AccountID3
FROM
    Accounts AS a1
    LEFT OUTER JOIN Accounts AS a2 ON a2.AssignedTo = a1.AccountID
    LEFT OUTER JOIN Accounts AS a3 ON a3.AssignedTo = a2.AccountID
WHERE
    a1.AssignedTo=@Referrer AND PyramidPosition=@Position

(3)设计数据库以支持树检索。例如,添加一个引用路径列,如下所示(string):

AccountID        Referrer        ReferrerPath
1                NULL            NULL
2                1               /1/
3                2               /1/2/
4                3               /1/2/3/
5                2               /1/2/

然后检索间接子节点就简单多了:

SELECT * FROM Accounts WHERE ReferrerPath LIKE '/1/%';

给出直接或间接引用帐户ID 1的所有行。当然,更改referrer现在需要更新所有间接引用,以使路径保持最新。