Создание дерева в базе данных - PullRequest
3 голосов
/ 17 мая 2011

У меня есть база данных с именем dtEmploye с полями

employe_id
имя
Фамилия
boss_id , который имеет рекурсивное отношение к employee_id , где у меня есть код XXX

У меня есть код, но есть какая-то ошибка, которая показывает «Указанное приведение неверно.»

private void btntree_Click(object sender, EventArgs e)
    {
        DataTable vec = sel("SELECT * FROM dtemployee");
        treeView1.Nodes.Clear();
        foreach (DataRow dr in vec.Rows)
        {
            if ((int)dr["boss_id"] == XXX)
            {
                TreeNode parent = new TreeNode();
                parent.Text = dr["name"+"surname"].ToString();
                string value = dr["employe_id"].ToString();
                parent.Expand();
                treeView1.Nodes.Add(parent);
                sublevel(parent, value);
            }
        }
    }
    public int sublevel(TreeNode parent, string id)
    {
        DataTable ch = sel("SELECT * FROM dtEmploye WHERE boss_id=" + id);
        if (dtEmploye.Rows.Count > 0)
        {
            foreach (DataRow dr in ch.Rows)
            {
                TreeNode child = new TreeNode();
                child.Text = dr["name"+"surname"].ToString().Trim();
                string temp = dr["employe_id"].ToString();
                child.Collapse();
                parent.Nodes.Add(child);
                sublevel(child, temp);
            }
            return 0;
        }
        else
        {
            return 0;
        }
    }
    protected DataTable sel(string select)
    {
        NpgsqlDataAdapter adpt = new NpgsqlDataAdapter(select, con);
        DataTable dt2 = new DataTable();
        adpt.Fill(dt2);
        return dt2;
    }

Ответы [ 4 ]

1 голос
/ 18 мая 2011

Почему бы не сделать это в SQL?Вы можете выполнить рекурсивный запрос, а затем добавить все узлы, просматривая набор данных в коде, используя сортировку, чтобы определить, какому узлу принадлежит подузел.

;WITH Tree (ID, [NAME], PARENT_ID, Depth, Sort) AS
(
    SELECT ID, [NAME], PARENT_ID, 0 AS Depth, CONVERT(varchar(255), [Name]) AS Sort FROM Category
    WHERE PARENT_ID = 0
    UNION ALL
    SELECT CT.ID, CT.[NAME], CT.PARENT_ID, Parent.Depth + 1 AS Depth, 
    CONVERT(varchar(255), Parent.Sort + ' | ' + CT.[NAME]) AS Sort
    FROM Category CT
    INNER JOIN Tree as Parent ON Parent.ID = CT.PARENT_ID
)

-- HERE IS YOUR TREE, Depths gives you the level starting with 0 and Sort is the Name based path
SELECT ID, [NAME], PARENT_ID, Depth, Sort FROM Tree
ORDER BY Sort
1 голос
/ 17 мая 2011

Попробуйте это

    if ((int)dr["boss_id"] == XXX && DBNull.Value != dr["boss_id"])
    {
        TreeNode parent = new TreeNode();
        parent.Text = dr["name"].ToString() + dr["surname"].ToString();
        string value = dr["employe_id"].ToString();
        parent.Expand();
        treeView1.Nodes.Add(parent);
        sublevel(parent, value);
    }
0 голосов
/ 18 мая 2011

Вы должны быть осторожны при использовании приведения, если вы не знаете тип объекта заранее. Помните, что приведение действительно только в отношениях «есть». Для всего остального вам нужно сделать конвертацию.

Например:

если у вас есть

class Truck : Automobile

и

class Car : Automobile

Тогда

Automobile truck = new Truck();
Truck refoftruck = (Truck)truck; //correct usage;

Car badrefofTruck = (Car)truck; //will not work;

Хотя автомобиль действительно является автомобилем (тип грузовика объекта), он также не грузовик, поэтому актерский состав не будет работать. Чтобы перейти от грузовика к машине, вам нужно написать какое-то обращение.

То же самое верно для объекта и int. Хотя почти все наследуется от объекта, они могут расходиться дальше по цепочке наследования. Вы не знаете, какой тип объекта, поэтому вы не знаете, является ли он int, string, double и т. Д. Таким образом, актеры в этой ситуации обычно плохая идея. Все приведения должны быть вверх или вниз по цепочке наследования.

Чтобы преобразовать строку в int (обратите внимание на слово Convert not cast), вы должны использовать:

Convert.ToInt32(strObject.ToString());

Надеюсь, это поможет и прояснит. Конечно, перед выполнением преобразования вам, вероятно, нужно проверить, что объект не равен нулю.

0 голосов
/ 17 мая 2011

Единственное место, где я вижу, что вы получаете эту ошибку:

if ((int)dr["boss_id"] == XXX)

Попробуйте сделать что-то вроде этого:

if(dr["boss_id"] != null && dr["boss_id"] is int && (int)dr["boss_id"] == XXX)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...