Toon posts:

[VB.NET/ASP.NET] Recursieve functie *

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik ben nu bezig om een tree te laten genereren uit een database. Die database (MySQL) ziet er alsvolgt uit:
code:
1
2
3
4
5
6
7
8
9
ID    Parent     Titel
1     4          Titel4.1
2     3          Titel3.1
3     0          Titel3

4     0          Titel4
5     0          Titel5
6     5          Titel5.1
7     6          Titel5.1.1


Het resultaat dat ik wil hebben is dat ik alle titels wil hebben waar een titel onderzit. Dit wou ik ook met SQL doen (zie dit topic) maar dat wil helaas niet met een query.

In dit voorbeeld wil ik dus het volgende resultaat bereiken:
code:
1
2
3
4
Titel3
Titel4
Titel5
  Titel5.1

Ik heb al een leuke sub gemaakt die zichzelf aanroept, maar volgens mij kan dit helemaal niet. De sub ziet er alsvolgt uit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Private Sub DisplayChildren(Optional ByVal Parent As Integer = 0)
        Dim objCmdTree As New OdbcCommand("SELECT * FROM Content WHERE Parent = ?", objConn)
        objCmdTree.Parameters.Add(New OdbcParameter("", Parent))

        Try
            objConn.Open()
            Dim TreeReader As OdbcDataReader
            TreeReader = objCmdTree.ExecuteReader

            While TreeReader.Read()
                'oTree.Add("root", "a" & TreeReader.GetInt32(0).ToString, TreeReader.GetString(2))
                testSTR = testSTR & TreeReader.GetString(2) & vbCrLf
                DisplayChildren(TreeReader.GetInt32(0))
            End While
        Catch ex As Exception

        End Try
    End Sub
In deze code zal objCmdTree steeds veranderen en dus zal hij niet meer doorgaan in de parent loop. Per Child zou er dus een nieuwe Command aangemaakt moeten worden maar hoe doe je dit?
Please help me op weg. Thnx

  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 09:19

gorgi_19

Kruimeltjes zijn weer op :9

Sloop bij het debuggen eerst eens de try-catch weg. Sowieso zijn er betere methodieken om een boom te bouwen.

Zie hiervoor [rml]EfBe in "[ VB.NET] Treeview + Subnodes (van Subnod..."[/rml]

[ Voor 65% gewijzigd door gorgi_19 op 07-02-2005 13:11 ]

Digitaal onderwijsmateriaal, leermateriaal voor hbo


  • MrSleeves
  • Registratie: Februari 2004
  • Laatst online: 10-04 19:23

MrSleeves

You'll thank me later.

objCmdTree is lokaal en als je de sub aanroept, dan is het gewoon weer een nieuwe variabele. Als de Sub klaar is en terugvalt in de bovenliggende, dan is objCmdTree gewoon weer wat het was.

Let alleen wel op: objConn is niet lokaal en kan je maar één keer openen.
Je wilt niet heel veel queries tegelijk laten lopen. Denk dat je beter met een DataSet/DataTable de query uit kan laten voeren. En dan sluit je de verbinding weer. En als je dan de sub opnieuw aanroept, dan heb je ook weer een gesloten verbinding.

Deze methode heet recursiviteit / recursieve functies e.d.

30Drie Web Design & IT Consultancy | Raven Consultancy Services


Verwijderd

Op het eerste zicht lijkt het me dat deze code wel degelijk zal werken op 1 puntje na:
Jij maakt een Command aan met objConn als parameter. Later open je die connectie. Vanaf de 2de call naar die sub zul je een exception krijgen dat de connectie reeds open is. Je kan dus best voor je opent checken of de connectie reeds open is en deze sluiten en terug openen, of op de connectie verder werken. (zonder objConn.open()) op te roepen.
Checken of een connectie open is doe je met de property State op het connectionobject.

Verwijderd

Topicstarter
Verwijderd schreef op maandag 07 februari 2005 @ 13:15:
Op het eerste zicht lijkt het me dat deze code wel degelijk zal werken op 1 puntje na:
Jij maakt een Command aan met objConn als parameter. Later open je die connectie. Vanaf de 2de call naar die sub zul je een exception krijgen dat de connectie reeds open is. Je kan dus best voor je opent checken of de connectie reeds open is en deze sluiten en terug openen, of op de connectie verder werken. (zonder objConn.open()) op te roepen.
Checken of een connectie open is doe je met de property State op het connectionobject.
Ik heb het geprobeerd op jouw manier. Ik roep de functie alsvolgt aan:
code:
1
2
3
objConn.Open()
DisplayChildren(0)
objConn.Close()


Maar dan krijg ik de volgende melding: Aan deze verbinding is al een open DataReader gekoppeld die eerst moet worden afgesloten.

Dus ik zou ook een nieuwe datareader moeten aanmaken ben ik bang voor.

Over de hashTable heb ik totaal geen verstand van. Heb al ff gezocht op internet maar kan niet echt een plausibele uitleg vinden. En in mijn boeken (ASP.NET in 21 Dagen, Developing Web Applications in VB.NET en nog 3) kan ik heb ook niet vinden. Iemand misschien een leuke link hierover. In de MSDN vind ik het trouwens ook niet echt goed uitgelegd

  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 09:19

gorgi_19

Kruimeltjes zijn weer op :9

En wat snap je er niet aan? Wat jouw methodiek is min of meer een garantie dat je de boel gaat opblazen.

Digitaal onderwijsmateriaal, leermateriaal voor hbo


Verwijderd

Topicstarter
gorgi_19 schreef op maandag 07 februari 2005 @ 13:46:
En wat snap je er niet aan? Wat jouw methodiek is min of meer een garantie dat je de boel gaat opblazen.
In een hashTable kan je dus key-and-value paren opslaan. Heel leuk. Je kan ze sorteren etc. Maar hoe zou je dat moeten toepassen bij een Tree. Ik heb namelijk 3 waardes: ID, parent en Titel.
Ik snap het nut nog niet echt van een hashTable. Misschien moet het kwartje ook nog ff vallen. Ik had er trouwens ook nog nooit van gehoord hoor.

  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 09:19

gorgi_19

Kruimeltjes zijn weer op :9

Verwijderd schreef op maandag 07 februari 2005 @ 13:50:
[...]


In een hashTable kan je dus key-and-value paren opslaan. Heel leuk. Je kan ze sorteren etc. Maar hoe zou je dat moeten toepassen bij een Tree. Ik heb namelijk 3 waardes: ID, parent en Titel.
Ik snap het nut nog niet echt van een hashTable. Misschien moet het kwartje ook nog ff vallen. Ik had er trouwens ook nog nooit van gehoord hoor.
Key: ID
Value: TreeItemClass (met de properties ID, Parent en Title)

Nut: snel opzoeken van zaken, zonder dat je daarbij continue een databaseconnectie moet maken.

[ Voor 9% gewijzigd door gorgi_19 op 07-02-2005 13:52 ]

Digitaal onderwijsmateriaal, leermateriaal voor hbo


Verwijderd

Als je even na mekaar uitschrijft wat jij doet kom je tot het volgende:

objConn.open()
DisplayChildren(0)

Nu zijn we opnieuw in de sub DisplayChildren

....
objConn.Open()
....

Nu keren we terug uit DisplayChildren

objConn.Close()

Wat er dus gebeurt is dat je opnieuw 2x je connectie na elkaar opent.

Door die Reader kom je inderdaad in de problemen. Een mogelijkheid is om ook je connection lokaal in de functie met new aan te maken en per call naar DisplayChildren dus een verbinding openen. Een andere mogelijkheid is zoals reeds aangehaald met een DataSet werken.


code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
        Public Sub BouwBoom()
                Dim conn As New SqlConnection(ConfigurationSettings.AppSettings("connectionString"))
                Dim adapter As New SqlDataAdapter("SELECT * FROM Content", conn)
                Dim ds As New DataSet
                adapter.Fill(ds)
                conn.Dispose()
                DisplayChildren(0, ds)
        End Sub
        Private Sub DisplayChildren(byval parent as integer, byval ds as DataSet)
                Dim dv as DataView = ds.Tables("Content").DefaultView
                dv.RowFilter = "Parent = " + parent.ToString()
                For i as integer = 0 to dv.Count - 1
                      Dim dr as DataRow = dv.Item(i).Row
                      '  in dr zitten nu de kolommen van je tabel 
                      '  dr("kolomnaam") geeft je de waarde terug
                      testSTR = testSTR & dr("Titel") & vbCrLf
                      DisplayChildren(dr("ID"), ds)
                Next
                
        End Sub


Dit zou het zo ongeveer moeten zijn.

[ Voor 9% gewijzigd door Verwijderd op 07-02-2005 14:01 . Reden: Kleine foutjes ]


Verwijderd

Topicstarter
ik heb je voorbeeld gebruikt maar hij doet het nog niet .. Ik dacht dat ik al een beetje into the asp.net/vb.net was .. niet dus! Ik pak mn boek over ado.net maar weer ff erbij!

Hij gaat trouwens in de mist bij de rowfilter.

Verwijderd

Verwijderd schreef op maandag 07 februari 2005 @ 14:53:


Hij gaat trouwens in de mist bij de rowfilter.
Kun je mij precies zeggen wat je van foutmeldingen krijgt ??

Ik kan niet 100% garanderen dat mijn code volledig werkt (heb het uit m'n hoofd ff neergeschreven) maar de idee zit er wel in van hoe het moet...

[ Voor 25% gewijzigd door Verwijderd op 07-02-2005 14:59 ]


Verwijderd

Topicstarter
ik heb mijzelf en jullie op een dwaalspoor gezet. Ik gebruik een tree component (van obout.com) en die maakt automatisch de tree. Alles wat ik moet is een lijst geven met het id, de parent en de titel en dan komt er automatisch de tree uitrollen.

Dus ik hoefde helemaal niet zo moeilijk te doen. Ik heb het nu al werkende. Het enige wat ik nog wil is dat het laagste level niet getoond wordt. Dus zoals bij Windows Explorer dat je alleen de directories ziet en dat je de files onder die directory pas ziet als je op de directory klikt. Ik denk dat ik dit helaas wel met een hashTable of een dataset/dataview moet doen.
Pagina: 1