Считыватель данных SQL с обновлением для дерева - PullRequest
1 голос
/ 27 июня 2019

У меня есть таблица в SQL Express, которая содержит некоторые данные, используемые в сценарии типа TreeView.

У него есть родительско-дочерние отношения, но все это в одной таблице.

Моя цель - установить значение уровня отступа, и я подумал о том, чтобы выбрать данные, используя читатель, чтобы начать с первой записи. У него нет родителя, поэтому уровень остается 0, если запись имеет родителя, он должен проверить значение отступа родителя и затем добавить 1.

Моя проблема в том, что все уровни начинаются с 0, когда он проходит через мой код, он устанавливает уровень отступа 1 для второй записи, но когда он получает запись три, он показывает уровень родителя трех: все еще 0. даже если я обновил его, и когда я смотрю в таблицу, он установлен на 1. Кажется, что мой выбор уже сохранил данные в считывателе.

Структура таблицы:

image

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();
    }
}

1 Ответ

0 голосов
/ 27 июня 2019

Такой подход не сработает. Ваш читатель не увидит обновления, выполненные вашими обновлениями.

Простым подходом было бы создание итеративного набора обновлений. скажем,

  • Начните со всех уровней до нуля
  • уровень массового обновления до 0, где "parent_id = parent_id_ref"
update relationship set level = 0 where parent_id = parent_id_ref
  • массовое обновление дочерних элементов любого родителя, для которого уже установлен уровень
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
  • повторять предыдущий оператор до тех пор, пока число затронутых строк за одну итерацию не станет равным 0.

Все это можно сделать в одной команде SQL с циклом вокруг последнего шага, проверяющим значение @@ rowcount после оператора

...