оптимизировать древовидную популяцию из БД - PullRequest
0 голосов
/ 06 мая 2011

Ниже приведен код, который я использовал для загрузки данных в дерево в базе данных! Но я чувствую, что он немного запаздывает при поиске ... Есть ли способ оптимизировать его?

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    Try
        If Not IsPostBack Then
            PopulateRootLevel("0", "ALL")
        End If
    Catch ex As Exception
        MSGMgr.errHandlerSys(ex.Message, lblMsg)
    End Try
End Sub

Private Sub PopulateRootLevel(ByVal LvlCD As String, ByVal scheme As String)

    Dim objConn As New SqlConnection(DBMgr.asyncADOCnnStr("SQL"))

    Dim objCommand As SqlCommand
    If scheme = "ALL" Then
        objCommand = New SqlCommand("SELECT DISTINCT LevelCD, Level1 IsChecked, LevelCD+Level2+'|'+Level1+'|'+CASE WHEN Level3 IS NULL THEN '' ELSE Level3 END ID, Level3 Scheme, GroupNo, Descriptions Title, (SELECT DISTINCT COUNT(*) FROM i_Menu_Access WHERE GroupNo = prt.GroupNo and SubItemNo1='0' AND LevelCD='0' AND ItemNo <> '0') SubItemCnt FROM i_Menu_Access prt WHERE ItemNo = '0' AND LevelCD = '" & LvlCD & "' ORDER BY GroupNo", objConn)
    Else
        objCommand = New SqlCommand("SELECT DISTINCT LevelCD, Level1 IsChecked, LevelCD+Level2+'|'+Level1+'|'+CASE WHEN Level3 IS NULL THEN '' ELSE Level3 END ID, Level3 Scheme, GroupNo, Descriptions Title, (SELECT DISTINCT COUNT(*) FROM i_Menu_Access WHERE GroupNo = prt.GroupNo and SubItemNo1='0' AND LevelCD='0' AND ItemNo <> '0') SubItemCnt FROM i_Menu_Access prt WHERE ItemNo = '0' AND LevelCD = '" & LvlCD & "' AND Level3 = @Scheme ORDER BY GroupNo", objConn)
        objCommand.Parameters.Add("@Scheme", SqlDbType.VarChar).Value = scheme
    End If

    Dim da As New SqlDataAdapter(objCommand)
    Dim dt As New DataTable()
    da.Fill(dt)

    For Each dr As DataRow In dt.Rows
        Dim child As New TreeNode()
        child.Text = dr("Title").ToString().Trim()
        child.Value = dr("ID").ToString().Trim()

        Dim GrpNo As String = dr("GroupNo").ToString().Trim()

        child.ToolTip = "Click to get Child"
        child.SelectAction = TreeNodeSelectAction.SelectExpand
        child.CollapseAll()

        tvMenuTable.Nodes.Add(child)
        PopulateSubLevel(GrpNo, LvlCD, child, scheme)
    Next

End Sub

Private Sub PopulateSubLevel(ByVal parentid As Integer, ByVal LvlCD As String, ByVal parentNode As TreeNode, ByVal scheme As String)

    Dim objConn As New SqlConnection(DBMgr.asyncADOCnnStr("SQL"))

    Dim objCommand As SqlCommand
    If scheme = "ALL" Then
        objCommand = New SqlCommand("SELECT DISTINCT LevelCD, Level1 IsChecked, LevelCD+Level2+'|'+Level1+'|'+CASE WHEN Level3 IS NULL THEN '' ELSE Level3 END ID, Level3 Scheme, ItemNo, cast(groupno as varchar)+'|'+cast(itemno as varchar)+'|'+cast(subitemno1 as varchar) ID2, Descriptions Title, (SELECT DISTINCT COUNT(*) FROM i_Menu_Access WHERE GroupNo = prt.GroupNo AND ItemNo = prt.ItemNo AND SubItemNo1 <> '0' AND SubItemNo2 = '0' AND LevelCD = '0') SubItemCnt FROM i_Menu_Access prt WHERE LevelCD = @LvlCD AND GroupNo = @parentID AND ItemNo <> '0' AND SubItemNo1 = '0' ORDER BY ItemNo", objConn)
        objCommand.Parameters.Add("@parentID", SqlDbType.Int).Value = parentid
        objCommand.Parameters.Add("@LvlCD", SqlDbType.VarChar).Value = LvlCD
    Else
        objCommand = New SqlCommand("SELECT DISTINCT LevelCD, Level1 IsChecked, LevelCD+Level2+'|'+Level1+'|'+CASE WHEN Level3 IS NULL THEN '' ELSE Level3 END ID, Level3 Scheme, ItemNo, cast(groupno as varchar)+'|'+cast(itemno as varchar)+'|'+cast(subitemno1 as varchar) ID2, Descriptions Title, (SELECT DISTINCT COUNT(*) FROM i_Menu_Access WHERE GroupNo = prt.GroupNo AND ItemNo = prt.ItemNo AND SubItemNo1 <> '0' AND SubItemNo2 = '0' AND LevelCD = '0') SubItemCnt FROM i_Menu_Access prt WHERE LevelCD = @LvlCD AND GroupNo = @parentID AND ItemNo <> '0' AND SubItemNo1 = '0' AND Level3 = @Scheme ORDER BY ItemNo", objConn)
        objCommand.Parameters.Add("@parentID", SqlDbType.Int).Value = parentid
        objCommand.Parameters.Add("@LvlCD", SqlDbType.VarChar).Value = LvlCD
        objCommand.Parameters.Add("@Scheme", SqlDbType.VarChar).Value = scheme
    End If

    Dim da As New SqlDataAdapter(objCommand)
    Dim dt As New DataTable()
    da.Fill(dt)

    For Each dr As DataRow In dt.Rows
        Dim child As New TreeNode()
        child.Text = dr("Title").ToString().Trim()
        child.Value = dr("ID").ToString().Trim()

        Dim ID() As String
        ID = dr("ID2").ToString().Trim().Split("|")

        child.ToolTip = "Click to get Child"
        child.SelectAction = TreeNodeSelectAction.SelectExpand
        child.CollapseAll()

        parentNode.ChildNodes.Add(child)
        PopulateThirdLevel(ID(0), ID(1), LvlCD, child, scheme)
    Next

End Sub

Private Sub PopulateThirdLevel(ByVal lvlOneID As Integer, ByVal lvlTwoID As Integer, ByVal LvlCD As String, ByVal parentNode As TreeNode, ByVal scheme As String)

    Dim objConn As New SqlConnection(DBMgr.asyncADOCnnStr("SQL"))

    Dim objCommand As SqlCommand
    If scheme = "ALL" Then
        objCommand = New SqlCommand("SELECT DISTINCT LevelCD, Level1 IsChecked, LevelCD+Level2+'|'+Level1+'|'+CASE WHEN Level3 IS NULL THEN '' ELSE Level3 END ID, Level3 Scheme, ItemNo, SubItemNo1, cast(groupno as varchar)+'|'+cast(itemno as varchar)+'|'+cast(subitemno1 as varchar) ID2, Descriptions Title FROM i_Menu_Access WHERE LevelCD = @LvlCD AND GroupNo = @lvlOneID AND ItemNo = @lvlTwoID AND ItemNo <> '0' AND SubItemNo1 <> '0' AND SubItemNo2 = '0' ORDER BY SubItemNo1", objConn)
        objCommand.Parameters.Add("@lvlOneID", SqlDbType.Int).Value = lvlOneID
        objCommand.Parameters.Add("@lvlTwoID", SqlDbType.Int).Value = lvlTwoID
        objCommand.Parameters.Add("@LvlCD", SqlDbType.VarChar).Value = LvlCD
    Else
        objCommand = New SqlCommand("SELECT DISTINCT LevelCD, Level1 IsChecked, LevelCD+Level2+'|'+Level1+'|'+CASE WHEN Level3 IS NULL THEN '' ELSE Level3 END ID, Level3 Scheme, ItemNo, SubItemNo1, cast(groupno as varchar)+'|'+cast(itemno as varchar)+'|'+cast(subitemno1 as varchar) ID2, Descriptions Title FROM i_Menu_Access WHERE LevelCD = @LvlCD AND GroupNo = @lvlOneID AND ItemNo = @lvlTwoID AND ItemNo <> '0' AND SubItemNo1 <> '0' AND SubItemNo2 = '0' AND Level3 = @Scheme ORDER BY SubItemNo1", objConn)
        objCommand.Parameters.Add("@lvlOneID", SqlDbType.Int).Value = lvlOneID
        objCommand.Parameters.Add("@lvlTwoID", SqlDbType.Int).Value = lvlTwoID
        objCommand.Parameters.Add("@LvlCD", SqlDbType.VarChar).Value = LvlCD
        objCommand.Parameters.Add("@Scheme", SqlDbType.VarChar).Value = scheme
    End If

    Dim da As New SqlDataAdapter(objCommand)
    Dim dt As New DataTable()
    da.Fill(dt)

    For Each dr As DataRow In dt.Rows
        Dim child As New TreeNode()
        child.Text = dr("Title").ToString().Trim()
        child.Value = dr("ID").ToString().Trim()

        Dim ID() As String
        ID = dr("ID2").ToString().Trim().Split("|")

        child.SelectAction = TreeNodeSelectAction.SelectExpand
        child.CollapseAll()

        parentNode.ChildNodes.Add(child)
        Populate4thLevel(ID(0), ID(1), ID(2), LvlCD, child, scheme)
    Next
End Sub

Private Sub Populate4thLevel(ByVal lvlOneID As Integer, ByVal lvlTwoID As Integer, ByVal lvl3rdID As Integer, ByVal LvlCD As String, ByVal parentNode As TreeNode, ByVal scheme As String)

    Dim objConn As New SqlConnection(DBMgr.asyncADOCnnStr("SQL"))

    Dim objCommand As SqlCommand
    If scheme = "ALL" Then
        objCommand = New SqlCommand("SELECT DISTINCT LevelCD, Level1 IsChecked, LevelCD+Level2+'|'+Level1+'|'+CASE WHEN Level3 IS NULL THEN '' ELSE Level3 END ID, Level3 Scheme, ItemNo, SubItemNo2, Descriptions Title FROM i_Menu_Access WHERE LevelCD = @LvlCD AND GroupNo = @lvlOneID AND ItemNo = @lvlTwoID AND SubItemNo1 = @lvl3rdID AND SubItemNo2 <> '0' ORDER BY SubItemNo2", objConn)
        objCommand.Parameters.Add("@lvlOneID", SqlDbType.Int).Value = lvlOneID
        objCommand.Parameters.Add("@lvlTwoID", SqlDbType.Int).Value = lvlTwoID
        objCommand.Parameters.Add("@lvl3rdID", SqlDbType.Int).Value = lvl3rdID
        objCommand.Parameters.Add("@LvlCD", SqlDbType.VarChar).Value = LvlCD
    Else
        objCommand = New SqlCommand("SELECT DISTINCT LevelCD, Level1 IsChecked, LevelCD+Level2+'|'+Level1+'|'+CASE WHEN Level3 IS NULL THEN '' ELSE Level3 END ID, Level3 Scheme, ItemNo, SubItemNo2, Descriptions Title FROM i_Menu_Access WHERE LevelCD = @LvlCD AND GroupNo = @lvlOneID AND ItemNo = @lvlTwoID AND SubItemNo1 = @lvl3rdID AND SubItemNo2 <> '0' AND Level3 = @Scheme ORDER BY SubItemNo2", objConn)
        objCommand.Parameters.Add("@lvlOneID", SqlDbType.Int).Value = lvlOneID
        objCommand.Parameters.Add("@lvlTwoID", SqlDbType.Int).Value = lvlTwoID
        objCommand.Parameters.Add("@lvl3rdID", SqlDbType.Int).Value = lvl3rdID
        objCommand.Parameters.Add("@LvlCD", SqlDbType.VarChar).Value = LvlCD
        objCommand.Parameters.Add("@Scheme", SqlDbType.VarChar).Value = scheme
    End If

    Dim da As New SqlDataAdapter(objCommand)
    Dim dt As New DataTable()
    da.Fill(dt)

    For Each dr As DataRow In dt.Rows
        Dim child As New TreeNode()
        child.Text = dr("Title").ToString().Trim()
        child.Value = dr("ID").ToString().Trim()

        child.SelectAction = TreeNodeSelectAction.SelectExpand
        child.CollapseAll()

        parentNode.ChildNodes.Add(child)
    Next
End Sub

Ответы [ 2 ]

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

Вы можете добавить свои таблицы данных в набор данных и настроить отношения между родителями и дочерними элементами в наборе данных.

Вот полный, чистый и оптимизированный код.Я писал комментарии, где это необходимо

DataTable dtbl1=new DataTable();//parent datatable
DataTable dtbl2=new DataTable();//child datatable

DataSet ds = new DataSet();
ds.Tables.Add(dtbl1);
ds.Tables.Add(dtbl2);
ds.Relations.Add("Children", dtbl1.Columns["dtb1ID"], dtbl2.Columns["dtbl2ID"]);//define parent child relation in dataset

if (ds.Tables[0].Rows.Count > 0)
{
    trv.Nodes.Clear();
    Int32 count = 0;

    foreach(DataRow masterRow in  ds.Tables[0].Rows)
    {
        TreeNode masterNode = new TreeNode((String)masterRow["dtbl1ColumnYouWantToDisplay"], Convert.ToString(masterRow["dtbl1ID"]));
        trv.Nodes.Add(masterNode);

        foreach (DataRow childRow in masterRow.GetChildRows("Children"))
        {
            TreeNode childNode = new TreeNode((String)childRow["dtbl2ColumnYouWantToDisplay"], Convert.ToString(childRow["dtb2ID"]));
            masterNode.ChildNodes.Add(childNode);
            count++;
        }
    }
    trv.ExpandAll();
}
0 голосов
/ 06 мая 2011

Что ж, если вы правильно спроектируете свою базу данных, вам понадобится всего одна функция для получения и заполнения узлов на любом уровне. Например, давайте рассмотрим пример таблицы базы данных «Items», такой как

ItemId int NOT NULL PK
ItemText varchar(200)
ParentId int NULL FK

Обратите внимание, что мы поместили FK в ParentId с той же таблицей Items, и это может быть NULL, указывая элементы корневого уровня. Теперь вы можете получать предметы на любом уровне, используя запрос, например

SELECT ItemId, ItemText, ParentId FROM Items WHERE ParentId = @ParentId

Если вы хотите получить элементы корневого уровня, передайте @ParentId как NULL - получите расширение любого узла и получите дочерние элементы, передайте ItemId для этого узла как ParentId в запрос выше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...