ADO.NET on osa .NET-alustaa ja se tarjoaa työkaluja tietokantojen käsittelyyn.

Tietokantayhteyden muodostaminen

Tietokantayhteyden muodostamiseksi tarvitaan connection string, jossa määritellään mm. tietokantapalvelimen nimi/osoite sekä käyttäjätunnus/salasana. Connection stringien esimerkkejä löytyy mm. osoitteesta http://connectionstrings.com/. Tietokantayhteyden muodostamiseen käytetään DbConnection-luokasta periytyviä luokkia. Microsoft SQL Serverin tapauksessa tällainen luokka on SqlConnection (system.Data.SqlClient -nimiavaruus). Muille tietokannoille voi etsiä tarjoajia mm. Wikipedian artikkelista ADO.NET.

Määritellään yhteys Microsoft SQL Serverin tietokantaan kauppa osoitteessa .\SQLEXPRESS

// connection string
string connStr = @"Data Source=.\SQLEXPRESS;Initial Catalog=kauppa;Integrated Security=SSPI;";
// määritellään yhteys
SqlConnection conn = new SqlConnection(connStr);

Esim. MySQL:ään yhteyden määrittely on samanlainen, paitsi että SqlConnection korvataan luokalla MySqlConnection (MySql.Data.MySqlClient -nimiavaruus, pitää asentaa ja lisätä referenssi - lataa connector) ja tietysti connection string muutetaan tietokantaa vastaavaksi.

Tietokantojen käsittelyyn tarkoitettujen luokkien luominen kannattaa laittaa using-lohkoon, jolloin varatut resurssit vapautetaan lohkon päätteeksi. Tämän huomiotta jättäminen voi johtaa siihen, että yhteydet jäävät auki, eikä tietokanta salli enää uusia yhteyksiä.

string connStr = @"Data Source=.\SQLEXPRESS;Initial Catalog=kauppa;Integrated Security=SSPI;";
// luodaan yhteys
using (SqlConnection conn = new SqlConnection(connStr))
{
	// avaa yhteys
	conn.Open();
	// suorita kysely tms.
	// sulje yhteys
	conn.Close();
}

Komentojen luominen ja suorittaminen

Komennot periytyvät luokasta DbCommand ja SQL Serverin tapauksessa sellainen on SqlCommand ja MySQl:n tapauksessa MySqlCommand (käyttöönotto kuten MySqlConnection-luokalla yllä). Komennot tarvitsevat tietokantayhteyden sekä komentotekstin. Komennot voivat olla tietoa hakemattomia (NonQuery), yhden arvon hakevia (skalaari, Scalar) tai useita rivejä hakevia. Tietoa hakemattomia komentoja ovat esim. rivin lisääminen, päivittäminen ja poistaminen. Tosin nekin komennot palauttavat tiedon siitä kuinka moneen riviin komento vaikutti. Yhden tiedon hakevista komennoista on esimerkkinä tuotteiden lukumäärän hakeminen. Monta riviä voidaan saada, kun haetaan esim. kaikki tuotteet.

Yhden arvon hakeminen

Yhden arvon hakemiseen on tarkoitettu metodi ExecuteScalar, joka palauttaa ensimmäisen rivin ensimmäisen sarakkeen arvon.

Haetaan tuoteryhmien lukumäärä

// connection string
string connStr = @"Data Source=.\SQLEXPRESS;Initial Catalog=kauppa;Integrated Security=SSPI;";
// komentoteksti
string query = "SELECT COUNT(*) FROM tuoteryhma";
int count;

// luodaan yhteys
using (SqlConnection conn = new SqlConnection(connStr))
{
	// luodaan komento
	using (SqlCommand cmd = new SqlCommand(query, conn))
	{
		// avataan yhteys
		conn.Open();
		// suoritetaan komento ja sijoitetaan lukumäärä muuttujaan
		count = (int)cmd.ExecuteScalar();
		// suljetaan yhteys
		conn.Close();
	}
}

Ei-kysely

Ei-kyselyiden suorittamiseen on metodi ExecuteNonQuery.

Poistetaan tuoteryhmä, jonka id on 1

// connection string
string connStr = @"Data Source=.\SQLEXPRESS;Initial Catalog=kauppa;Integrated Security=SSPI;";
// kysely
string query = "DELETE FROM tuoteryhma WHERE id=1";
int count;

// luodaan yhteys
using (SqlConnection conn = new SqlConnection(connStr))
{
	// luodaan komento
	using (SqlCommand cmd = new SqlCommand(query, conn))
	{
		// avataan yhteys
		conn.Open();
		// ExecuteNonQuery palauttaa lukumäärän kuinka moneen riviin komento vaikutti
		// esim. kuinka monta riviä poistettiin
		count = cmd.ExecuteNonQuery();
		// suljetaan yhteys
		conn.Close();
	}
}

Useiden rivien hakeminen

Useiden rivien hakemiseen on parikin vaihtoehtoa: DataReader ja DataAdapter. Näiden ero on se, että DataReader lukee dataa rivi kerrallaan, kun taas DataAdapter lukee ensin kaikki rivit ja palauttaa tuloksen vasta sitten. Tästä syystä DataReader kuluttaa vähemmän muistia ja on nopeampi siinä mielessä, että riviä voi aloittaa käsittelemään seuraavan rivin vasta ollessa tulossa. DataReaderiä voi lukea vain eteenpäin, eli aiemmin käsitelty rivi ei ole enää saatavilla. DataReaderissä ei myöskään ole tauluja.

Haetaan tietokannasta tuoteryhmät

// connection string
string connStr = @"Data Source=.\SQLEXPRESS;Initial Catalog=kauppa;Integrated Security=SSPI;";
// kysely
string query = "SELECT id,nimi FROM tuoteryhma";

List<Tuoteryhma> tuoteryhmat = new List<Tuoteryhma>();

// luodaan yhteys
using (SqlConnection conn = new SqlConnection(connStr))
{
	// luodaan komento
	using (SqlCommand cmd = new SqlCommand(query, conn))
	{
		// avataan yhteys
		conn.Open();
		// suoritetaan komento
		using (SqlDataReader reader = cmd.ExecuteReader())
		{
			// luetaan rivi kerrallaan
			while (reader.Read())
			{
				Tuoteryhma tr = new Tuoteryhma();
				// id on ensimmäisessä sarakkeessa
				tr.Id = reader.GetInt32(0);
				// nimi on toisessa sarakkeessa
				tr.Nimi = reader.GetString(1);

				tuoteryhmat.Add(tr);
			}
		}
		// suljetaan yhteys
		conn.Close();
	}
}

DataAdapter on sopivampi, jos suorittaa useamman kyselyn samalla kertaa tai dataa pitää pyöritellä useaan kertaa.

Parametrien välittäminen

Parametreja ei pidä laittaa komentoon näin
string nimi = "Emolevyt";
string query = "SELECT id,nimi FROM tuoteryhma WHERE nimi='" + nimi + "'";

vaan sitä varten komennolla on Parameters -ominaisuus. Komentotekstissä parametri merkitään @-merkillä.

public Tuoteryhma HaeTuoteryhmaNimella(string nimi)
{
	// connection string
	string connStr = @"Data Source=.\SQLEXPRESS;Initial Catalog=kauppa;Integrated Security=SSPI;";
	// kysely
	// @tr_nimi on parametri
	string query = "SELECT id,nimi FROM tuoteryhma WHERE nimi=@tr_nimi";

	Tuoteryhma tuoteryhma = null;

	// luodaan yhteys
	using (SqlConnection conn = new SqlConnection(connStr))
	{
		// luodaan komento
		using (SqlCommand cmd = new SqlCommand(query, conn))
		{
			// lisätään parametrin arvo
			cmd.Parameters.Add("@tr_nimi", SqlDbType.NVarChar).Value = nimi;
			// avataan yhteys
			conn.Open();
			// suoritetaan komento
			using (SqlDataReader reader = cmd.ExecuteReader())
			{
				// luetaan rivi kerrallaan
				while (reader.Read())
				{
					tuoteryhma = new Tuoteryhma();
					// id on ensimmäisessä sarakkeessa
					tuoteryhma.Id = reader.GetInt32(0);
					// nimi on toisessa sarakkeessa
					tuoteryhma.Nimi = reader.GetString(1);
				}
			}
			// suljetaan yhteys
			conn.Close();
		}
	}
	return tuoteryhma;
}