Ansluta vid start eller per fråga. C#-MSSQL

Permalänk
Medlem

Ansluta vid start eller per fråga. C#-MSSQL

Hur gör man i vanliga fall om man tex har ett grafiskt c# program som ställer frågor mot en SQL till en datagridview.
Ansluter man till SQL-servern med connectionsträngen när man startar programmet och skickar runt anslutningen till funktionerna.
Eller skapar man en ny anslutning, kopplar upp och kopplar ner för varje knapptryckning.

Upplever inte att något går segare med att koppla upp och koppla ner utan fördelen är mer att programmet kan vara igång i all oändlighet och även om anslutningen till SQL är knackig så funkar detta bättre.

Finns det ett rätt och fel?

Visa signatur

K#

Permalänk
Medlem

Om du inte gör något speciellt med anslutningen kommer connection-poolen hålla rätt på den, dvs .NET kommer att återanvända samma anslutning flera gånger trots att du skapar nya SqlConnections (förutsatt att det är samma anslutning givetvis, byter du tex connection-strängen kanske det inte går att återanvända en gammal anslutning).

Permalänk
Medlem

Det finns en kod jag hittade och rekonstruerade lite och som jag alltid använder för att använda datagridview i C#. Prova denna:

OBS kalla denna koden i mouse click event.

public void PopulateDataGrid() { string connString = "server=" + dbServer + "; port=" + dbPort + "; database=" + dbDB + "; Uid=" + dbUser + "; Password=" + dbPass + ";"; mysqlCon = new MySqlConnection(connString); mysqlCon.Open(); MySqlDataAdapter MyDA = new MySqlDataAdapter(); string sqlSelectAll = "SELECT * FROM table WHERE Username = '" + username + "' AND Mailadress = '" + MailAdress + "';"; MyDA.SelectCommand = new MySqlCommand(sqlSelectAll, mysqlCon); DataTable table = new DataTable(); MyDA.Fill(table); bSource = new BindingSource(); bSource.DataSource = table; dataGridView1.DataSource = bSource; connected = true; mysqlCon.Dispose; mysqlCon.Close(); } private void button6_Click(object sender, EventArgs e) { PopulateDataGrid(); }

Denna använder jag om jag ska komma åt min databas och återge den i en datagrid. Notera att inte missa en enda grej här, då kommer det inte funka ^^,

Vad jag vet så kan du skapa en kontakt, stänga den och sedan skapa en ny igen.

mysqlCon = new mysqlCon();
mysqlCon.Open();
mysqlCon.Close();
mysqlCon.Dispose();

Du slöar allvarligt inte ner programmet så mycket om du skapar nya kontakter då och då, alternativt kan du börja läsa på att cross-thread'a, du startar en ny tråd för koden för att höja prestandan och inte belasta programmet så mycket

//Hoppas det hjälpte

Visa signatur

Citera om du vill ha svar, hjälpte jag dig, gilla svaret!
Felkod40

Permalänk
Medlem

tänkte bara nämna att man kan använda using när man hanterar sitt connection-object. using ger en implicit try/finally där objektets dispose-metod körs och objektet går "ur scope".

exempel:

using (var connection = new SqlConnection(connectionString)) // implicit kod-block using (var command = new SqlCommand(commandText, connection)) { command.Connection.Open(); using (var reader = command.ExecuteReader()) { while (reader.Read()) { // gör något trevligt med datan... } } // här körs reader.Dispose() command.Connection.Close(); } // här körs command.Dispose(), sedan connection.Dispose()

Visa signatur

as far as we can tell, the massacre went well...

Permalänk
Medlem
Skrivet av jovnas:

tänkte bara nämna att man kan använda using när man hanterar sitt connection-object. using ger en implicit try/finally där objektets dispose-metod körs och objektet går "ur scope".

exempel:

using (var connection = new SqlConnection(connectionString)) // implicit kod-block using (var command = new SqlCommand(commandText, connection)) { command.Connection.Open(); using (var reader = command.ExecuteReader()) { while (reader.Read()) { // gör något trevligt med datan... } } // här körs reader.Dispose() command.Connection.Close(); } // här körs command.Dispose(), sedan connection.Dispose()

Lämpligare vore ju om man skapa en separat klass för mysql kommandon ^^ smidigare och stiligare i Form1. Hursomhelst, hur ska det där hjälpa honom med att lägga in i datagrid'en om han inte vet hur man gör :3

Din kod funkar säkert, men han vet kanske inte hur man hanterar den. Men däremot kanske du kan ge honom ett litet tips?

För vad jag förstått så vill @atman köra en SQL query (fråga) mot en databas och återge allt resultat (tabellens innehåll) i en datagridvy. Och verkar samtidigt vilja få lite extra kunskap om detta, bra ^^

Typ som:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Forms; using MySql.Data.MySqlClient; using System.Data; namespace DataGridViewExample { class SQLQuerys { //Skapa en string som skickar vidare all information för att kontakta databasen static string dbServer = "localhost", dbPort = "3306", dbDB = "myDatabase", dbUser = "root", dbPass = "password", userName, PassWord; //Skapa nu en metod, namnge den vad som helst public static void PopulateDataGrid(DataGridView dataGridView1) { //skapa nu kontakten och bidra med all information från ovan string connString = "server=" + dbServer + "; port=" + dbPort + "; database=" + dbDB + "; Uid=" + dbUser + "; Password=" + dbPass + ";"; //Skapa en ny MySQLConnection MySqlConnection mysqlCon = new MySqlConnection(connString); //Öppna kontakten mysqlCon.Open(); //Skapa en adapter MySqlDataAdapter MyDA = new MySqlDataAdapter(); //skriv ditt kommando, det du vill hämta från databasen. string sqlSelectAll = "SELECT * FROM Errands WHERE Username = '" + userName + "' AND Password = '" + PassWord + "';"; //skicka vidare kommandot till adaptern och även din kontaktinformation MyDA.SelectCommand = new MySqlCommand(sqlSelectAll, mysqlCon); //Skapa ett nytt "bord" eller en tabell över den information vi får ut av frågan DataTable table = new DataTable(); //Fyll tabellen MyDA.Fill(table); //Ange vart våran datasource ska få sin data ifrån som sedan skickas till datagridvyn. BindingSource bSource = new BindingSource(); bSource.DataSource = table; dataGridView1.DataSource = bSource; //Stäng nu mysql kontakten. mysqlCon.Close(); mysqlCon.Dispose(); } } }

Skapa en datagridvy i designer läget, om du inte kan göra det via kod.
när du gjort det, skapa en fin knapp som det står "Hämta data" eller liknande på..
Dubbelklicka på knappen om du inte vill döpa din click event till något speciellt (manuellt)

Återanvänds nu i Form1.cs som:

private void button1_Click(object sender, EventArgs e) { try { //DataGridView's modifier kanske måste sättas till public. SQLQuerys.PopulateDataGrid(dataGridView1); } catch(Exception MySQLerror) { MessageBox.Show("Ett fel uppstod i programmet när data skulle hämtas. Felet hittades i: " + MySQLerror.Message); } }

Visa signatur

Citera om du vill ha svar, hjälpte jag dig, gilla svaret!
Felkod40

Permalänk
Medlem
Skrivet av freddyfresh:

Hursomhelst, hur ska det där hjälpa honom med att lägga in i datagrid'en om han inte vet hur man gör :3

Din kod funkar säkert, men han vet kanske inte hur man hanterar den. Men däremot kanske du kan ge honom ett litet tips?

nu framgår det ju faktiskt inte av ursprungsinlägget om atman vet hur man hanterar en DataGridView, men eftersom han frågar om en så specifik sak som hur man hanterar sin connection, så utgår jag från att han faktiskt känner till det.

mitt tips om using för hantering av objektens livslängd kvarstår (och det var nog egentligen riktat till dig freddy).
för svar på den ursprungliga frågan hänvisar jag till vbs svar.

Visa signatur

as far as we can tell, the massacre went well...

Permalänk
Medlem

aaah ^^ förstod ditt inlägg som ett svar på hans fråga :3 men samtidigt så var din beskrivning ganska bra för den förklarade ju fortfarande vart man skulle placera dispose och close, inget emot din lösning om jag ska säga så

Visa signatur

Citera om du vill ha svar, hjälpte jag dig, gilla svaret!
Felkod40

Permalänk
Medlem

Imho så om man inte använder using när man kan är det i det närmaste en bug.

Exempel-koden här visar det bra, det är lätt att göra fel när man sköter det manuellt (dvs, i exemplet är inte koden wrappad i en try-finally som den borde, kastas exception kommer ju anslutningen bli hängande)

Permalänk
Medlem
Skrivet av vb:

Imho så om man inte använder using när man kan är det i det närmaste en bug.

Exempel-koden här visar det bra, det är lätt att göra fel när man sköter det manuellt (dvs, i exemplet är inte koden wrappad i en try-finally som den borde, kastas exception kommer ju anslutningen bli hängande)

Jo, men då bör man egentligen placera try/catch/finally i metoden för att undvika att kontakten fortsätter eller inte avslutas. Men så går det när man skriver lite för fort ^^,

Uppskattas någon kod man postat?

Visa signatur

Citera om du vill ha svar, hjälpte jag dig, gilla svaret!
Felkod40

Permalänk
Skrivet av freddyfresh:

Jo, men då bör man egentligen placera try/catch/finally i metoden för att undvika att kontakten fortsätter eller inte avslutas. Men så går det när man skriver lite för fort ^^,

Uppskattas någon kod man postat?

Eller, som han skrev, så använder man using. Då avslutas alltid anslutningen

Visa signatur

Asus Striker II Extreme / XFX Geforce GTX 280 / Q9450 @ 3.6GHz/ TRUE Noctua 120/ 4x1GB Corsair TWIN3X2048-1333C9DHX / X25-M G2 80gb Velociraptor / Win 7 Ultimate x64/ Antec P190

MovieDatabase

Permalänk
Medlem
Skrivet av freddyfresh:

Uppskattas någon kod man postat?

jodå, det tror jag nog. Fast du får vara beredd på att få lite mothugg från tex mig om det finns förbättringspotential

När vi ändå är inne på spåret, nu såg jag att koden med stor sannolikhet är öppen för SQL injection oxå. Om det är en winforms-app spelar det kanske inte så stor roll, men om någon annan läser här och tänker använda den till tex en webapp så spelar det roll.

Man bör aldrig bygga ihop en sql-sats med strängar, det är väldigt lätt missar att skydda sig mot injections då. Istället kan man använda Parameters på Command-objektet för att lägga in dynamiska parametrar så som username och annat. Inte kritiskt om det man bygger inte behöver skyddas, men o andra sidan, varför inte göra på det bättre sättet direkt? Ingen risk att man senare lånar koden till ett program där det spelar roll eller att man vänjer sig vid att skriva osäker kod.

Permalänk
Medlem
Skrivet av KurreKula:

Eller, som han skrev, så använder man using. Då avslutas alltid anslutningen

SQL-anslutning stängs ju oavsett vilken kod man använt sålänge du lyckats koppla upp dig och sedan kör .Close och .Dispose på SQL-anslutningen. Sen beroende på prestanda man vill ha och hur väl man vill skydda koden och programmet från intrång m.m. är ju en annan sak.

Skrivet av vb:

jodå, det tror jag nog. Fast du får vara beredd på att få lite mothugg från tex mig om det finns förbättringspotential

När vi ändå är inne på spåret, nu såg jag att koden med stor sannolikhet är öppen för SQL injection oxå. Om det är en winforms-app spelar det kanske inte så stor roll, men om någon annan läser här och tänker använda den till tex en webapp så spelar det roll.

Min kod var riktad endast för Windows form application eftersom jag såg att han skulle använda en datagrid, utgick inte från något annat. Eftersom mina erfarenheter kring webbutveckling inte är så utvecklade som de kanske borde vara så är jag inte riktigt medveten om myslq injektioner på en sådan miljö. Ursäktar för eventuell förvirring.

Och det finns alltid förbättringar att göra i det här ämnet.

Visa signatur

Citera om du vill ha svar, hjälpte jag dig, gilla svaret!
Felkod40

Permalänk
Medlem
Skrivet av freddyfresh:

SQL-anslutning stängs ju oavsett vilken kod man använt sålänge du lyckats koppla upp dig och sedan kör .Close och .Dispose på SQL-anslutningen. Sen beroende på prestanda man vill ha och hur väl man vill skydda koden och programmet från intrång m.m. är ju en annan sak.

nja... det hänger ju på om något går fel eller inte.
exempelvis om DataAdapter.Fill() av någon anledning misslyckas och slänger ett Exception, så stängs inte anslutningen i din kod, utan blir hängande.

// ingen skriver sån här kod, utan det är enbart ett exempel! var connection = new SqlConnection(connectionString); var command = new SqlCommand(commandText, connection); connection.Open(); throw new Exception("Vi låtsas att detta är ett fel från tex. en DataAdapter"); // koden nedan kommer aldrig att köras, vilket lämnar connection öppen... connection.Close(); connection.Dispose();

using ger en try/finally, så att connection alltid stängs och disposas.

angående SQL-injections, så är det ju lika lätt att skriva ' or ''=' i en text-box i WinForms som på webben, så det är alltid en bra idé att använda parametrar.
(och det är ju lätt också! command.Parameters.AddWithValue("@UserName", userName); )

Visa signatur

as far as we can tell, the massacre went well...

Permalänk
Skrivet av freddyfresh:

SQL-anslutning stängs ju oavsett vilken kod man använt sålänge du lyckats koppla upp dig och sedan kör .Close och .Dispose på SQL-anslutningen. Sen beroende på prestanda man vill ha och hur väl man vill skydda koden och programmet från intrång m.m. är ju en annan sak.

Som många påpekat är detta inte alltid fallet. Ifall du skulle ha gjort en try / finally så visst, då är det samma sak. Så som det är skrivet nu är det runt ut sagt dåligt

Visa signatur

Asus Striker II Extreme / XFX Geforce GTX 280 / Q9450 @ 3.6GHz/ TRUE Noctua 120/ 4x1GB Corsair TWIN3X2048-1333C9DHX / X25-M G2 80gb Velociraptor / Win 7 Ultimate x64/ Antec P190

MovieDatabase