[C#] Classes: Resource in meerdere functies gebruiken

Pagina: 1
Acties:

  • Keess
  • Registratie: Augustus 2006
  • Laatst online: 27-11 08:21
Ik ben pas begonnen met C#, en ben nu aan het OOP hoofdstuk toe.
Nu wilde ik een class maken met MSSQL functies, verbinding, query's etc.
maar nu heb ik het volgende probleem.


C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
    class MSSQL
    {
        public bool     _connected = false;
        public string   _error = "";

        //SqlConnection Conn;

        public bool dbconnect()
        {
            try
            {
                SqlConnection Conn = new SqlConnection("server=PCLAPTOP\\SQLEXPRESS;integrated security=true;database=test;");
                Conn.Open();
            }
            catch (System.Data.SqlClient.SqlException ex)
            {
                this._error = "Error tijdens de database verbinding.\n\n" + ex.Message + "\nNr: " + ex.Number;
                return false;
            }
            return true;
        }

        public bool query(string MSSQLCommand)
        {
            try
            {
                SqlCommand cmd = new SqlCommand(MSSQLCommand, Conn);
                cmd.ExecuteReader();
            }
            catch (System.Data.SqlClient.SqlException ex)
            {
                this._error = "Error tijdens query.\n\n" + ex.Message;
                return false;
            }
            return true;
        }
    }

MSSQL.cs

Nu init. ik hem vanuit Form1:
C#:
1
MSSQL SQL = new MSSQL();


en dan maak ik de verbinding:

C#:
1
SQL.dbconnect();


Dit gaat goed, alleen wanneer ik nu een query wil uitvoeren vanuit Form1 met:
C#:
1
SQL.query(textBox1.Text);


zegt hij uiteraard dat Conn 'niks' is. (The name 'Conn' does not exists in the current context.)

Hoe zorg ik ervoor dat Conn wordt meegegeven aan de functue query(), Global, of aan de functie meegeven, of ...

Bij voorbaat dank,

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Je declareert Conn in de dbconnect method, terwijl je die in de class zélf moet declareren. Iets met scopes enzo ;)

http://www.google.com/search?hl=en&q=c%23+scopes

[ Voor 18% gewijzigd door RobIII op 28-11-2006 22:31 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • Paul
  • Registratie: September 2000
  • Nu online
Wat is er zo speciaal aan een SqlConnection dat je die niet een stap globaler zou kunnen declareren? Het scope-verhaal lijk je te snappen getuige je _error en _connected :?

"Your life is yours alone. Rise up and live it." - Richard Rahl
Rhàshan - Aditu Sunlock


  • Keess
  • Registratie: Augustus 2006
  • Laatst online: 27-11 08:21
Natuurlijk :)

Ik had SqlConnection Conn; al geprobeerd, deze is, en blijft Null natuurlijk, door dit te wijzigen naar:
C#:
1
SqlConnection Conn = new SqlConnection("server=PCLAPTOP\\SQLEXPRESS;integrated security=true;database=test;"); 


en te verwijderen in de dbconnect functie, werkt het. Ietsje te lang achter de pc gezeten vandaag :P

Bedankt!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Keess schreef op dinsdag 28 november 2006 @ 22:46:
Natuurlijk :)

Ik had SqlConnection Conn; al geprobeerd, deze is, en blijft Null natuurlijk, door dit te wijzigen naar:
C#:
1
SqlConnection Conn = new SqlConnection("server=PCLAPTOP\\SQLEXPRESS;integrated security=true;database=test;"); 


en te verwijderen in de dbconnect functie, werkt het. Ietsje te lang achter de pc gezeten vandaag :P

Bedankt!
Euh... ik weet niet of ik je post goed begrijp, maar ik ben toch wel even benieuwd naar je code nu ;)

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • Keess
  • Registratie: Augustus 2006
  • Laatst online: 27-11 08:21
Komtie...

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
    class MSSQL
    {
        public bool     _connected = false;
        public string   _error = "";

// Was SqlConnection Conn;
        SqlConnection Conn = new SqlConnection("server=PCLAPTOP\\SQLEXPRESS;integrated security=true;database=test;");

        public bool dbconnect()
        {
            try
            {
                Conn.Open();
            }
            catch (System.Data.SqlClient.SqlException ex)
            {
                this._error = "Error tijdens de database verbinding.\n\n" + ex.Message + "\nNr: " + ex.Number;
                return false;
            }
            return true;
        }

        public bool query(string MSSQLCommand)
        {
            try
            {
                SqlCommand cmd = new SqlCommand(MSSQLCommand, Conn);
                cmd.ExecuteReader();
                //cmd.Connection.Close();
            }
            catch (System.Data.SqlClient.SqlException ex)
            {
                this._error = "Error tijdens query.\n\n" + ex.Message;
                return false;
            }
            return true;
        }
    }


Alleen nu krijg ik de error dat de reader nog open staat, kon zo snel niet vinden hoe dit weer te 'resetten' enig idee? cmd.ExecuteReader();

(edit: Ik kan evt. per query de Conn opengooien en aan het eind ervan weer dichtgooien, maar dit lijkt me niet de snelste en mooiste manier.)

code:
1
There is already an open DataReader associated with this Command which must be closed first.

[ Voor 4% gewijzigd door Keess op 28-11-2006 22:58 ]


  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Daar was ik al bang voor ;)
Ik zou dat stukje over scopes nog eens goed lezen ;) Er is geen reden om in de class zélf al de variabele meteen in gebruik te nemen met een new SqlConnection statement (jouw regel 7); dat kan prima in de dbconnect zoals je dat al had; je dient enkel de variabele zélf buiten de dbconnect method te declareren.

Zo dus:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    class MSSQL
    {
        <snip>

        SqlConnection Conn;

        public bool dbconnect()
        {
            try
            {
                Conn = New SqlConnection("...");
                Conn.Open();
            <snip>
            }
        }

        public bool query(string MSSQLCommand)
        {
            <Hier gebruik je gewoon Conn>
            <snip>
        }
    }


En wat betreft die datareader die nog open is; lees de foutmelding eens goed: "...must be closed first" ;)

Los daarvan zou ik de connectiestring meegeven aan de dbconnect method i.p.v. hardcoded in je class te zetten ;)

[ Voor 45% gewijzigd door RobIII op 28-11-2006 23:13 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • Keess
  • Registratie: Augustus 2006
  • Laatst online: 27-11 08:21
Ah, dat werkt ook en lijkt mij ook een stuk efficienter.

Zie nu pas dat closed een link is 8)7 zo is het alweer een stuk duidelijker :)

[ Voor 92% gewijzigd door Keess op 28-11-2006 23:24 ]


  • Keess
  • Registratie: Augustus 2006
  • Laatst online: 27-11 08:21
Zo moet het gaan lukken, bedankt d:)b :

[ Voor 10% gewijzigd door Keess op 28-11-2006 23:28 ]


  • Paul
  • Registratie: September 2000
  • Nu online
Je Query geeft een bool terug? Kun je dan niet beter ExecuteNonQuery gebruiken? Of beter nog: meteen je functie anders noemen :P Een query vraagt iets op, en momenteel doe je er niets mee :P
Je vergeet trouwens ook de InvaldiOperationException die Open() kan gooien :)

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
namespace test
{
  class MSSQL
  {
    public bool IsConnected
    {
      get { return (Conn != null) && ((Conn.State & ConnectionState.Open) == ConnectionState.Open); }
    }

    private SqlConnection Conn;

    public bool DbConnect()
    {
      if (Conn != null) return true;

      try
      {
        Conn = new SqlConnection("server=PCLAPTOP\\SQLEXPRESS;integrated security=true;database=test;");
        Conn.Open();
      }
      catch (System.Data.SqlClient.SqlException ex)
      {
        _error = "Error tijdens de database verbinding.\n\n" + ex.Message + "\nNr: " + ex.Number;
        return false;
      }
      catch (InvalidOperationException ex)
      {
        // Deze is niet belangrijk genoeg ofzo? :P 
      }

      return true;
    }

    public bool ExecuteNonQuery(string MSSQLCommand)
    {
      if (!IsConnected) return false;

      try
      {
        using ( SqlCommand cmd = new SqlCommand(MSSQLCommand, Conn); )
        {
          cmd.ExecuteNonQuery();
        }
      }
      catch (System.Data.SqlClient.SqlException ex)
      {
        _error = "Error tijdens query.\n\n" + MSSQLCommand + "\n" + ex.Message;
        return false;
      }
      return true;
    }
  }
}

[ Voor 1% gewijzigd door Paul op 29-11-2006 00:14 . Reden: IsConnected-check @ ExecuteNonQuery toegevoegd ]

"Your life is yours alone. Rise up and live it." - Richard Rahl
Rhàshan - Aditu Sunlock


  • Keess
  • Registratie: Augustus 2006
  • Laatst online: 27-11 08:21
Dit werkt helemaal _/-\o_

Zal nu is proberen om de 'query' functie aan te passen zodat er data opgehaald kan worden etc.

d:)b

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Ik weet trouwens niet wat je precies wat je wilt bereiken. Maar het is niet handig om maar 1 Connectie over je hele applicatie te gebruiken. Het is meestal beter om voor elke query ( of eigenlijk elke groep query's ) een nieuwe connectie te maken. Op die manier wordt er gebruik gemaakt van Connection pooling

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • whoami
  • Registratie: December 2000
  • Laatst online: 18:04
Op die manier wordt er gebruik gemaakt van Connection pooling
Kan er gebruik gemaakt worden van .... ;)

Iig, het is idd geen goed idee om de connectie langer open te houden dan nodig.

https://fgheysels.github.io/


  • Keess
  • Registratie: Augustus 2006
  • Laatst online: 27-11 08:21
Ben nu net een stuke over ConnectionPooling aan het lezen, wat ik er tot nu uit begrijp is dat er 1 verbinding gemaakt wordt, gesloten kan worden, en daarna weer opgevraagd kan worden zonder de hele verbinding opnieuw te initialiseren?

En ConnectionPooling=true mee te nemen in de ConnectionString..

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Keess schreef op woensdag 29 november 2006 @ 13:50:
Ben nu net een stuke over ConnectionPooling aan het lezen, wat ik er tot nu uit begrijp is dat er 1 verbinding gemaakt wordt, gesloten kan worden, en daarna weer opgevraagd kan worden zonder de hele verbinding opnieuw te initialiseren?

En ConnectionPooling=true mee te nemen in de ConnectionString..
Het idee achter ConnectionPooling is dat als jij Connection.Close() aanroept dat de connection dan niet daadwerkelijk geclosed hoeft te worden maar dat hij terug in de connection pool gestopt wordt. Als je een Connection.Open() doet dan wordt er eerst in de ConnectionPool gekeken of er nog een Connection is met dezelfde connection string en als dat zo is wordt die terug gegeven in plaats van een nieuwe connection te openen.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”

Pagina: 1