12. juni 2002 - 09:51Der er
15 kommentarer og 2 løsninger
Problem med visning af data
Hej alle. Jeg har en kode som denne:
<% Dim sql As SqlCommand = New SqlCommand("SELECT * FROM [tblMenu] WHERE [SubID] = 0", Conn) Dim rs As SqlDataReader = sql.ExecuteReader()
Do While rs.Read Response.Write("<img src='images/menu/" & rs("Image") & "' width='130' height='35'><br><br>") MakeSubs(rs("MenuID")) Loop %>
Den viser meget fint det den skal. MakeSubs funktionen skal så vise de underemner der er til menuemnet. I MakeSubs funktionen prøver jeg så at oprette en ny Reader for at kunne få fat i databasen og vise det nødvendige. Men jeg får fejlbeskeden "There is already an open DataReader associated with this Connection which must be closed first.". Hvad betyder det? Skal jeg så oprette endnu en connection, for at lave to readers på samme side, på samme tid?
Det hjælper jo ikke? Jeg kan naturligvis ikke lukke min connection før al kode er udført, og jeg skal vel ikke gentagne gange lukke og åbne connection? Der må da være en måde at have flere datareaders i gang på samme tid?
Du kan få flere datareaders igang ved at lave flere connections - en connection kan kun have med en datareader at gøre.
Når det er sagt så jo, man bør faktisk kalder close på connection objekter hver gang man er færdig med det og så åbne det igen når det skal bruges igen. Connection bliver ikke rigtigt lukket, men returneres til connection pool (hvorved en anden kan bruge den) og der er derfor ikke performance tab.
Det lyder jo fornuftigt nok, men jeg er egentligt stødt ind i endnu et problem mht denne funktion, det er nok lettest hvis lige jeg poster min kode:
<%@Import Namespace="System.Data"%>
<!--#Include File="../../includes/conn.aspx"-->
<script language="VB" runat="server">
Sub MakeSubs(SubID As Integer) Dim sqlSub As SqlCommand = New SqlCommand("SELECT * FROM [tblMenu] WHERE [SubID] = " & SubID, Conn) Dim rsSub As SqlDataReader = sqlSub.ExecuteReader()
Do While rsSub.Read Response.Write("<b>" & rsSub("Title") & "</b>") Loop End Sub
Hvis bare jeg kører denne kode, beklager MakeSubs funktionen sig over at Conn ikke er blevet erklæret, mit andet loop kører fint. Så har jeg prøvet at medsende Conn som et objekt, og så er det den siger at jeg kun kan have een datareader, skal jeg så lukke og åbne conn her, eller hvorledes gøres det?
Jeg skal nok give lidt flere point hvis du/i gider hjælpe en n00b lidt på vej :)
Sub MakeSubs(SubID As Integer) Dim sqlSub As SqlCommand = New SqlCommand("SELECT * FROM [tblMenu] WHERE [SubID] = " & SubID, Conn) Dim rsSub As SqlDataReader = sqlSub.ExecuteReader(CommandBehavior.CloseConnection)
Do While rsSub.Read Response.Write("<b>" & rsSub("Title") & "</b>") Loop End Sub
<% Dim sql As SqlCommand = New SqlCommand("SELECT * FROM [tblMenu] WHERE [SubID] = 0", Conn) Dim rs As SqlDataReader = sql.ExecuteReader(CommandBehavior.CloseConnection)
Do While rs.Read Response.Write("<img src='images/menu/" & rs("Image") & "' width='130' height='35'><br><br>") MakeSubs(rs("MenuID")) Loop %>
Så får jeg fejlen at Conn ikke erklæret... Det skyldes vel at Sub funktionerne kun kan bruge variabler som er dimensioneret/erklæret inden i selve funktionen? Hvordan løses det? :)
ASP.NET kører som sunedh også sagde med en ret effektiv connection pooling derfor skal du køre efter hovedreglen om hurtigst muligt at lukke og åbne connection og ikke gøre som jeg tror du gør nu, åbne og lukke i henholdsvis toppen og bunden af filen.
Lad være med at åbne din connection i det første åben den istedet for lige før du skal bruge den. Og luk den igen med CommandBehavior.CloseConnection, så får du den mest optimale hastighed.
Tak for tippet, men det løser jo ikke mit problem... Mit problem er jo at jeg ikke kan vise de relationelle data. Her er et eksempel på hvad jeg vil vise:
Nu er det jo somme tider lidt en religion hvordan man koder, så dette er ikke en opfording til en krig, men her er hvad jeg ville gøre:
1. opdel præsentation og logik i henholdsvis en aspx og en vb fil 2. undlad at bruge include filer - lav klasser i stedet, det er meget mere fleksiblet 3. til præsentation af data ville jeg anvende en repeater kontrol men en anden repeater kontrol indeni. Disse kan databindes direkte med din datareader. På den måde undgår du Response.Write, som man efter min mening aldrig bør bruge mere. Alternativt kunne man skrive de to forskellige SQL statement sammen til et og så kun anvende en repeater (og for den sags skyld datareader)
Så mit forslag kort: kig lidt på repeateren (evt. også datalist og datagrid) og adskil præsentation og logik.
Hej Sune. Jeg har fulgt dit råd og læst lidt på det... Men pinligt som det er, er jeg allerede stødt ind i problemer igen. Jeg har oprettet følgende kode:
:o) - det er jo bare fedt at det er kommet til at virke
sunedh
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.