简体   繁体   English

具有Treeview更新的SQL数据读取器

[英]SQL Data reader with Update for treeview

I have a table in SQL Express that contains some data used in TreeView type scenario. 我在SQL Express中有一个表,其中包含一些在TreeView类型方案中使用的数据。

It has parent-child relationship, but it is all in one table. 它具有父子关系,但都在一个表中。

My aim is to set an indent level value, and my thinking was to select the data, use the reader to start off with first record. 我的目的是设置一个缩进级别值,我的想法是选择数据,使用阅读器从第一个记录开始。 It has no parent so the level remains 0, if the record has a parent it must check the value of the indent of the parent and then add 1. 它没有父级,因此级别保持为0,如果记录具有父级,则它必须检查父级的缩进值,然后加1。

My problem is that all levels are 0 to start with, when it runs through my code, it sets the indent level to 1 on the second record, but when it gets to record three it show the level of parent of three is still 0. even though I updated it and when I look in the table it is set to 1. It seems that my select has already stored the data in the reader. 我的问题是开始时所有级别都是0,当它运行我的代码时,它在第二条记录上将缩进级别设置为1,但是当它记录到3时,它显示3的父级级别仍然为0。即使我已对其进行了更新,并在表中将其设置为1,也似乎已将其存储在读取器中。

Table Structure: 表结构:

图片

using (SqlConnection connection = new SqlConnection("Data Source=" + servername + "; MultipleActiveResultSets = true;Initial Catalog=" + database + "; Integrated Security=SSPI"))
{
    using (SqlCommand cmd = new SqlCommand("SELECT * FROM relationship", connection))
    {
        connection.Open();

        using (SqlDataReader reader = cmd.ExecuteReader())
        {
            // Check is the reader has any rows at all before starting to read.
            if (reader.HasRows)
            {
                // Read advances to the next row.
                while (reader.Read())
                {
                    int sid = reader.GetInt32(1);

                    //GET THE CURRENT LEVEL OF THE RECORD
                    int slevel = reader.GetInt32(4); /* THIS SECTION IS NOT SELECTING THE CURRENT DATA THAT WAS UPDATED IN MY UPDATE BELOW*/

                    //ADD TO CURRENT LEVEL
                    int newslevel = slevel + 1;

                    MessageBox.Show("MY ID IS " + sid + " MY LEVEL IS " + slevel);

                    using (SqlCommand upd = new SqlCommand("UPDATE relationship SET level=@newlevel WHERE parent_id_ref=@sid", connection))
                    {
                        upd.Parameters.AddWithValue("@sid", sid);
                        upd.Parameters.AddWithValue("@newlevel", newslevel);
                        int rows = upd.ExecuteNonQuery();
                    }
                }
            }
        }
        connection.Close();
    }
}

That approach won't work. 这种方法行不通。 Your reader won't see updates performed by your updates. 您的读者不会看到由您的更新执行的更新。

An easy approach would be to do an iterative set of updates. 一种简单的方法是进行迭代的更新集。 say, 说,

  • Start with all levels to null 从所有级别开始为空
  • bulk update level to 0 where "parent_id = parent_id_ref" 批量更新级别为0,其中“ parent_id = parent_id_ref”
update relationship set level = 0 where parent_id = parent_id_ref
  • bulk update children of any parent that already has their level set 批量更新已设置其级别的任何父级的子级
update relationship set level = parent.level + 1
from relationship child inner join relationship parent on parent.parent_id = child.parent_id_ref
where parent.level is not null and child.level = 0
  • repeat the the previous statement until the # of affected rows by one iteration is 0. 重复前面的语句,直到一次迭代的受影响行数为0。

This could all be done in a single SQL command, with the loop around the final step checking the @@rowcount value after the statement 所有这些都可以在一个SQL命令中完成,最后一步的循环检查语句后的@@ rowcount值

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM