19. maj 2006 - 13:40Der er
15 kommentarer og 1 løsning
'Genbrug' af et dataset
Jeg skal fylde nogle dropdownbokse med data fra forskellige tabeller og til den første gør jeg sådan:
Dim ds As DataSet ds = DB.SelDataSet("SELECT PartOfSystemText FROM tblPartOfSystem") ddlPartOfSystem.DataValueField = "PartOfSystemText" ddlPartOfSystem.DataSource = ds ddlPartOfSystem.DataBind() ddlPartOfSystem.Items.Insert(0, "Select Area...")
DB.SelDataSet er en funktion i en klasse, der returnerer et dataset.
Dette virker fint, men det ville jo være smart, hvis man kunne 'genbruge' ds til at fylde de andre dropdownlister i stedet for at skulle sige Dim ds1, Dim ds2, Din ds3 osv. - kan man det?
Hmm - dette hænger vist sammen med funktionen i klassen. Selv hvis jeg siger Dim ds1 og Dim ds2, så kan jeg med funktionen kun fylde een dropdownlist. Funtionen ser sådan ud:
Public Function SelDataSet(ByVal Sql As String) As DataSet
If Not OpenDB() Then Return Nothing End If
Dim objAdapter As New OleDbDataAdapter(Sql, Conn) Dim ds As New DataSet() Try objAdapter.Fill(ds, "Default") Return ds Catch Return Nothing Finally Conn.Dispose() End Try End Function
Du kan bare sætte datasættet som datasource på de andre dropdownlister også. Hvis du skal bruge data fra andre tabeller - kan du også bare proppe dem ind i dit dataset også. Mvh
Public Function SelDataSet(ByVal Sql As String, ByVal Tbl As String) As DataTable
If Not OpenDB() Then Return Nothing End If
Dim objAdapter As New OleDbDataAdapter(Sql, Conn) Dim ds As New DataSet() Try objAdapter.Fill(ds, Tbl) Return ds.Tables(Tbl) Catch Return Nothing Finally Conn.Dispose() End Try
End Function
Codebehind:
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim dt As DataTable dt = DB.SelDataSet("SELECT PartOfSystemText FROM tblPartOfSystem", "Default1") ddlPartOfSystem.DataValueField = "PartOfSystemText" ddlPartOfSystem.DataSource = dt ddlPartOfSystem.DataBind() ddlPartOfSystem.Items.Insert(0, "Select Area...")
'Fyldning ad datagrid dt = DB.SelDataSet("SELECT ID, ShortDescription FROM tblTasks", "Default2") dgTaskList.DataSource = dt dgTaskList.DataBind() End Sub
Dropdown fyldes fint nok, men datagriddet fyldes ikke. Hvis jeg undlader at fylde dropdown (udkommenterer), så fyldes datagrid?
Hvis jeg bruger to DataTables (dt1 og dt2), så udfyldes stadig kun dropdown?
Din variabel dt er bare en reference til den datatable der genereres af din metode, og det er så imod den datatable der peges på af referencen på det tidspunkt du udfører din databinding.
I dit scenarie - hvor du reelt ønsker at binde mod to forskellige datakilder - ville jeg nok selv arbejde med to referencer.... Så slipper du for at skulle "time" din databinding.
Prøv at arbejd med t1 og t2, og så debug ned igennem for at se om du reelt får data tilbage. Der burde ikke være ballade med det.
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim dt1 As DataTable dt1 = DB.SelDataSet("SELECT PartOfSystemText FROM tblPartOfSystem", "Default1") ddlPartOfSystem.DataValueField = "PartOfSystemText" ddlPartOfSystem.DataSource = dt1 ddlPartOfSystem.DataBind() ddlPartOfSystem.Items.Insert(0, "Select Area...")
'Fyldning ad datagrid Dim dt2 As DataTable dt2 = DB.SelDataSet("SELECT ID, ShortDescription FROM tblTasks", "Default2") dgTaskList.DataSource = dt2 dgTaskList.DataBind() End Sub
Jeg er desværre nødt til at køre VS 1.0 (mit firma har ikke .NET 2.0 klar endnu) og denne version kan jeg ikke få til at køre i debug.
Kører jeg ovennævnte kode, fyldes dropdown, men ikke datagrid. Hvis jeg udkommenterer koden til dropdown, så fyldes datagriddet pænt og nydeligt, så de virker fint hver for sig - hvad kan det være der driller, når begge dele kører?
Prøv at flyt koden til griddet op ovenover den til listen.... Jeg kunne forestille mig at det er din OpenDb der fejler, og hvis det er tilfældet skulle du få data i griddet, og ikke i listen. Mvh
Dim Conn As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; DATA SOURCE=" & OneLevelUp(HttpContext.Current.Server.MapPath("")) & ("QCCDatabases\x.mdb"))
Public Function OpenDB() As Boolean Try Conn.Open() Return True Catch Return False End Try End Function
Hvis du kalder Open på en forbindelse der allerede er åben - får du en fejl. Du kan checke på .State på din forbindelse. Tag eventuelt et kig på Data Access Application Block - den kan downloades på msdn. Mvh
Public Function SelDataSet(ByVal Sql As String, ByVal Tbl As String) As DataTable If Conn.State = ConnectionState.Closed Then If Not OpenDB() Then Return Nothing End If End If
Dim objAdapter As New OleDbDataAdapter(Sql, Conn) Dim ds As New DataSet() Try objAdapter.Fill(ds, Tbl) Return ds.Tables(Tbl) Catch Return Nothing Finally Conn.Dispose() End Try
End Function
men det virker stadig ikke.
Jeg har prøvet at aflæse mellem dropdown og datagrid og det er rigtigt, at OpenDB() fejler, men en aflæsning af ConnectionState.Closed viser, at forbindelsen er closed, så man skulle tro, at den gerne måtte åbnes igen?
Ahh ja - du kalder jo også dispose på din forbindelse - den går ikke hvis du vil genbruge den (hvilket som skrevet tidligere ikke er en anbefaling). Du newer den jo i forbindelse med deklerationen, og så disposer du den i din finally. Mvh
Jeg har nok ikke helt forstået det med IKKE at genbruge forbindelsen. Hvis man IKKE vil genbruge forbindelsen, skal man da åbne og lukke hver gang man gennemløber SelDataset eller hvordan?
Ja - jo kortere tid du holder på dine forbindelser... Jo bedre. Der er ikke noget stort overhead ved at oprette forbindelse i .net - så længe du benytter samme connectionstring hver gang, har du connectionpooling foræret. Mvh
Lige et lille tillægsspørgsmål vedr. datatables: kan man forespørge på en kombination af indholdet af to datatables, altså som man ville gøre med SQL på to tabeller?
Du kan - baseret på et filter - få et udsnit af din datatable (en som et DataRow[] object, eller som et view). Du kan desuden have relationer i dine tabeller - så du via relationen kan hente childs, så du har ikke den samme fleksibilitet som på sql-serveren. Mvh
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.