Avatar billede nzc Nybegynder
10. juli 2004 - 20:24 Der er 19 kommentarer og
1 løsning

flere odbcCommands på samme connection

Hej!

Jeg er i gang med at lave et lille adm-sys.

Forbindelse til database får jeg på følgende måde:
Jeg har en Controllerklasse der står for at oprette et objekt af typen "database". Constructoren i databaseklassen ser således ud:

private OdbcConnection con;
        public database()
        {       
            this.con = new OdbcConnection(MyConString);
        }

Herefter kalder Controllerklassen database.Open() som ser sådan ud:

public OdbcConnection OpenConnection()
        {
           
            try
            {
                this.con.Open();                
            }
            catch(Exception e)
            {
                throw e;
            }
            return this.con;
        }

Herefter kalder Controllerklassen den ønskede metode på databaseobjektet og derefter kaldes Close() på objektet og forbindelsen lukkes.
Når jeg vil trække data ud af databasen (eller putte noget i) så opretter jeg i hver metode i databaseklassen en OdbcCommand og en OdbcDataReader. Dette har nu vist sig at volde mig problemer :( Jeg har en metode i databaseklassen som kalder en anden metode i databaseklassen og dette gir mig en exception der lyder:

"There is already an open DataReader associated with this Connection which must be closed first."

Jeg er klar over at det er lidt et problem at jeg opretter OdbcDataReaders i hver metode. Hvordan ville I løses problemet ? Putte OdbcDataReaderen op i constructoren i databaseklassen? Det er mit umiddelbare bud, men kan det ikke også gi problemer ?

Håber I vil komme med et par gode forslag og lidt kritik på mit databaselag :)

NZC
Avatar billede arne_v Ekspert
10. juli 2004 - 20:28 #1
Den specifikke fejl kan løses ved at kalde Close metoden
på datareaderen inden du åbner den næste.
Avatar billede nzc Nybegynder
10. juli 2004 - 20:30 #2
det sjove er at det er inde i en while(reader.Read()) jeg kalder den anden metode og derfor skal bruge en ny reader :(
Avatar billede arne_v Ekspert
10. juli 2004 - 20:31 #3
Og umiddelbart synes jeg at et design med:

public ArrayList GetAllFoobars()
{
    // create OdbcCommand med SELECT
    // få OdbcDataReader via ExecuteQuery
    // hent alle data over som objekter i ArraryList
    // close OdbcDataReader
    // returner ArrayList
}

er den rigtige måde.
Avatar billede arne_v Ekspert
10. juli 2004 - 20:31 #4
Hvis du skal bruge 2 readere samtidigt så skal du bruge 2 connections.
Avatar billede arne_v Ekspert
10. juli 2004 - 20:31 #5
Hvilket vel også er meget logisk.
Avatar billede nzc Nybegynder
10. juli 2004 - 20:45 #6
Jeg forstår din GetAllFooBars() som at du, ligesom mig, ikke lader dine metoder oprette forbindelsen til databasen, men at den allerede er oprettet når dine metoder kaldes. Men det er jo lige netop det der går galt for mig. Jeg synes bare ikke det er særlig smart at lade hver metode oprette en forbindelse til databasen og udføre det den nu skal for derefter måske at kalde andre metoder der også åbner forbindelse. Men er det løsningen på mit problem måske ?!
Avatar billede arne_v Ekspert
10. juli 2004 - 20:47 #7
Hvis du husker at close datareaderen så vil det ikke gå galt.
Avatar billede arne_v Ekspert
10. juli 2004 - 20:49 #8
Ovenstående forventer en connection lavet i constructor.

Men i virkeligheden kunne man ligeså godt lave en ny connection i
selve metoden.

Når du opretter en .NET database connection så opretter du nemlig ikke
nødvendigvis en fysisk database connection, da .NET connection klasserne
har indbygget connection pool.
Avatar billede nzc Nybegynder
10. juli 2004 - 20:49 #9
problemet er jo at jeg er inde i en while(reader.Read()) når jeg skal bruge en ny reader. hvis jeg lukker den første så dør min while jo :(
Avatar billede arne_v Ekspert
10. juli 2004 - 20:56 #10
Så er det lidt mere komplekst. Men stadig muligt.

"one" med ny connection:

public ArrayList GetAllFoobars()
{
    // create OdbcConnection
    // create OdbcCommand med SELECT
    // få OdbcDataReader via ExecuteQuery
    // hent alle data over som objekter i ArraryList
    // close OdbcDataReader
    // close OdbcConnection
    // returner ArrayList
}

"two":

public ArrayList GetAllFooAndBars()
{
    // create OdbcConnection 1
    // create OdbcConnection 2
    // create OdbcCommand 1 med SELECT
    // få OdbcDataReader 1 via ExecuteQuery
    // while løkke
    // {
    //    hent data fra OdbcDataReader 1
    //    create OdbcCommand 2 med SELECT
    //    få OdbcDataReader 2 via ExecuteQuery
    //    hent data fra OdbcReader 2
    //    konstruere objekt fra de to readere og gem i ArrayList
    //    close OdbcDataReader 2
    // }
    // close OdbcDataReader 1
    // close OdbcConnection 1
    // close OdbcConnection 2
    // returner ArrayList
}
Avatar billede nzc Nybegynder
10. juli 2004 - 21:55 #11
Jeg har sat hver metode til at lave en connection så nu virker det med readeren i det mindste... Men... Hvorfor dælen vil reader.GetString(3) (3 er en varchar og jeg bruger en MySql db) kaste en exception når der er en Null-værdi i feltet ?

arne_v smid svar :)
Avatar billede arne_v Ekspert
10. juli 2004 - 21:58 #12
Hvilken exception ?
Avatar billede arne_v Ekspert
10. juli 2004 - 21:58 #13
svar
Avatar billede nzc Nybegynder
10. juli 2004 - 21:59 #14
specified cast not valid
Avatar billede arne_v Ekspert
10. juli 2004 - 22:01 #15
Prøv og udskriv:

reader.GetValue(3).GetType().Name

og se hvad det er for et objekt du står med.
Avatar billede nzc Nybegynder
10. juli 2004 - 22:07 #16
InvalidCastException
Avatar billede nzc Nybegynder
10. juli 2004 - 22:07 #17
hvis der er noget i feltet så er det et String objekt jeg står med
Avatar billede arne_v Ekspert
10. juli 2004 - 22:10 #18
Giver brug af reader.GetValue(3).GetType().Name også en exception ?
Avatar billede nzc Nybegynder
10. juli 2004 - 22:12 #19
ja

Jeg smider det lige ud som en selvstændig tråd :)
Avatar billede nzc Nybegynder
10. juli 2004 - 22:13 #20
Avatar billede Ny bruger Nybegynder

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.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester