Introduktion till ADO.NET

"Bild" 1: Vad är ADO.NET?

  1. ADO = "ActiveX Data Objects"
  2. Grunden för hur man (ska) hantera data i .NET
  3. Bland annat kan man kommunicera med databaser

Ur Wikipedia:

ADO.NET is a set of computer software components that programmers can use to access data and data services based on disconnected DataSets and XML. It is a part of the base class library that is included with the Microsoft .NET Framework. It is commonly used by programmers to access and modify data stored in relational database systems, though it can also access data in non-relational sources.

Microsoft själva skryter:

ADO.NET provides a rich set of components for creating distributed, data-sharing applications. It is an integral part of the .NET Framework, providing access to relational data, XML, and application data. ADO.NET supports a variety of development needs, including the creation of front-end database clients and middle-tier business objects used by applications, tools, languages, or Internet browsers.

Bild 2: En svamp-app

Vi kan tänka oss att vi ska jobba med svampar, till exempel på den här omoderna handdatorn. (Det hette så innan man uppfann smarttelefoner.) Men vi kan lika gärna tänka oss att vi kör programmet på någon annan typ av dator.

Tillämpningen "Svamparna" i en emulator

"Bild" 3: En svamptabell

Vi ska hålla reda på data om svampar:

Man kan göra en tabell:

Svampar
Nummer Namn Vikt Antal
1 kantarell 0.19 4
2 flugsvamp 0.43 126
3 toppslätskivling 0.22 0
5 hussvamp 13.34 7

Bild 4: Att jobba med data i ADO.NET

Vi vill jobba med data om svamparna i programmets minne, till exempel för att visa dem på skärmen, men dessutom ska de permanent lagras i en databas:

ADO.NET som sparar data

"Bild" 5: Två olika sätt att jobba med data i ADO.NET

"Connected approach" = uppkopplad lösning

  • Programmet är uppkopplat mot databasen hela tiden,
  • Man ändrar data i databasen allteftersom de ändras i programmet.

"Disconnected approach" = ej uppkopplad lösning

  • Programmet är inte uppkopplat mot en databas hela tiden.
  • Programmet har en särskild kopia av data, i egna tabeller.
  • Programmet kopplar upp sig mot databasen för att spara data, när det har jobbat klart.

Bild 6: Uppkopplad lösning ("tvålagerlösning")

Vi läser data från databasen när vi behöver det, och skriver det till databasen när vi gjort ändringar. Det går bra eftersom vi är uppkopplade mot databasen.

Uppkopplad lösning i ADO.NET

Bild 7: Ej uppkopplad lösning ("trelagerlösning")

Om vi inte är uppkopplade mot databasen, kan vi mellanlagra data i minnet. Vi får skriva ändringarna till databasen när vi så småningom kopplar upp oss igen.

Ej uppkopplad lösning i ADO.NET

"Bild" 8: Exempel på programkod för att hämta data

Här är programkod i C# som hämtar rader ur en tabell som heter Uppgifter. Vi använder en databashanterare som heter Microsoft SQL Server CE. Den klarar SQL, men inte lika avancerade SQL-kommandon som till exempel Microsofts stora databashanterare SQL Server Notera att det står SqlCe på många ställen i programmet, så det blir mycket att ändra om vi ska byta databashanterare.

    1   using System;
    2   using System.Drawing;
    3   using System.Collections;
    4   using System.Windows.Forms;
    5   using System.Data;
    6   using System.Data.Common;
    7   using System.Data.SqlServerCe;
    8   using System.IO;
    1   private void visaknappen_Click(object sender, System.EventArgs e)
    2   {
    3           string db_file_name = inboxen.Text;
    4           string db_connection_name = "Data Source=" + db_file_name;
    5           SqlCeConnection con = new SqlCeConnection();
    6           SqlCeCommand com = new SqlCeCommand();
    7   
    8           try 
    9           {
   10                   con.ConnectionString = db_connection_name;
   11                   con.Open();
   12                   com.Connection = con;
   13                   com.CommandText =
   14                           "select Nummer, Namn, Anteckningar, Prioritet " +
   15                           "from Uppgifter";
   16                   
   17                   SqlCeDataReader reader = com.ExecuteReader();
   18                   utboxen.Text = "";
   19                   while (reader.Read())
   20                   {
   21                           string raden = reader["Nummer"] + ", " + 
   22                                   reader["Namn"] + ", ..., " +
   23                                   reader["Prioritet"] + ", " + "\r\n";
   24                           utboxen.Text += raden;
   25                   }
   26   
   27                   MessageBox.Show("Visning klar.");
   28           }
   29           catch (SqlCeException ex) 
   30           {
   31                   MessageBox.Show("Det blev nåt fel: " +
   32                           ex.Errors[0].Message);
   33           }
   34           finally 
   35           {
   36                   con.Close();
   37           }
   38   }

"Bild" 9: Exempel på programkod för att ta bort alla raderna

    1   private void tömknappen_Click(object sender, System.EventArgs e)
    2   {
    3           string db_file_name = inboxen.Text;
    4           string db_connection_name = "Data Source=" + db_file_name;
    5           SqlCeConnection con = new SqlCeConnection();
    6           SqlCeCommand com = new SqlCeCommand();
    7   
    8           try 
    9           {
   10                   con.ConnectionString = db_connection_name;
   11                   con.Open();
   12                   com.Connection = con;
   13                   com.CommandText = "delete from Uppgifter";
   14                   com.ExecuteNonQuery();
   15                   MessageBox.Show("Tömning klar.");
   16           }
   17           catch (SqlCeException ex) 
   18           {
   19                   MessageBox.Show("Det blev nåt fel: " +
   20                           ex.Errors[0].Message);
   21           }
   22           finally {
   23                   con.Close();
   24           }
   25   }

"Bild" 10: Spara en rad i databasen

    1   private void db_insert_row(SqlCeConnection con,
    2           SqlCeCommand com, int Nummer, string Namn,
    3           string Anteckningar, int Prioritet) 
    4   {
    5           string query = "insert into Uppgifter " +
    6                   "(Nummer, Namn, Anteckningar, Prioritet) " +
    7                   "values (" + Nummer + ", '" + Namn + "', '" +
    8                   Anteckningar + "', " + Prioritet + ")";
    9           
   10           com.CommandText = query;
   11           com.ExecuteNonQuery();
   12   }

"Bild" 11: Spara tre exempelrader

    1   private void fyllknappen_Click(object sender, System.EventArgs e)
    2   {
    3           string db_file_name = inboxen.Text;
    4           string db_connection_name = "Data Source=" + db_file_name;
    5           SqlCeConnection con = new SqlCeConnection();
    6           SqlCeCommand com = new SqlCeCommand();
    7   
    8           try 
    9           {
   10                   con.ConnectionString = db_connection_name;
   11                   con.Open();
   12                   com.Connection = con;
   13                   db_insert_row(con, com, 1, "Träna", "Stenhårt!", 2);
   14                   db_insert_row(con, com, 2, "Vila", "Max 30 min", 1);
   15                   db_insert_row(con, com, 3, "Arbeta", "60h/vecka!", 3);
   16                   con.Close();
   17                   MessageBox.Show("Fyllning klar.");
   18           }
   19           catch (SqlCeException ex) 
   20           {
   21                   MessageBox.Show("Det blev nåt fel: " +
   22                                   ex.Errors[0].Message);
   23                   con.Close();
   24           }
   25   }

"Bild" 12: Mimer Data Provider

Ladda ner för Visual Studio 2013: Tisdagstest1MimerText.zip

Här är ett textbaserat program ("konsolprogram") som använder Mimer för att hämta data ur tabellen Personer. Skapad som en Console Application med Visual C# i Visual Studio 2013. Nu använder vi MimerConnection i stället för SqlCeConnection, och så vidare.

Obs! Av någon anledning fungerar det inte att koppla upp sig mot basen.oru.se, så vi använder en lokal databas. (Däremot fungerar ODBC-dataadaptern nedan.)

Mer om Mimer Data Provider: Accessing Mimer SQL from ADO.NET using Mimer Data Provider

    1   using System;
    2   using System.Collections.Generic;
    3   using System.Linq;
    4   using System.Text;
    5   using System.Threading.Tasks;
    6   using Mimer.Data.Client;
    7   
    8   namespace Tisdagstest1MimerText
    9   {
   10       class Program
   11       {
   12           static void Main(string[] args)
   13           {
   14               System.Console.WriteLine("Hämtar data...");
   15   
   16               MimerConnection con = new MimerConnection();
   17               con.ConnectionString =
   18                   "database=lokaltompatestbas;user id=dbtek0;password=gazonk";
   19               con.Open();
   20               MimerCommand com =
   21                   new MimerCommand("select id, namn from personer ", con);
   22               MimerDataReader reader = com.ExecuteReader();
   23               while (reader.Read())
   24               {
   25                   String id = reader["id"].ToString();
   26                   String namn = reader["namn"].ToString();
   27                   System.Console.WriteLine("ID = " + id + ", namn = " + namn);
   28               }
   29               reader.Close();
   30               con.Close();
   31               System.Console.WriteLine("Tryck en tangent för att avsluta!");
   32               System.Console.ReadKey();
   33           }
   34       }
   35   }

"Bild" 13: Data Provider for ODBC

Ladda ner för Visual Studio 2013: Tisdagstest2OdbcText.zip

Om det inte finns någon dataadapter för den databas man vill använda, eller om den inte fungerar, kan man använda en dataadapter byggd på ODBC. Då kan man komma åt alla datakällor som går att nå via ODBC. (Det fungerar även med Mimer-servern på basen.oru.se.)

Mer om hur man kan använda ODCB-dataadaptern med Mimer: ADO.NET

    1   using System;
    2   using System.Collections.Generic;
    3   using System.Linq;
    4   using System.Text;
    5   using System.Threading.Tasks;
    6   using System.Data.Odbc;
    7   
    8   namespace Tisdagstest2OdbcText
    9   {
   10       class Program
   11       {
   12           static void Main(string[] args)
   13           {
   14               System.Console.WriteLine("Hämtar data...");
   15   
   16               OdbcConnection con = new OdbcConnection();
   17               con.ConnectionString =
   18                   "driver=mimer;database=lokaltompatestbas;uid=dbtek0;pwd=gazonk";
   19               con.Open();
   20               OdbcCommand com =
   21                   new OdbcCommand("select id, namn from personer ", con);
   22               OdbcDataReader reader = com.ExecuteReader();
   23               while (reader.Read())
   24               {
   25                   String id = reader["id"].ToString();
   26                   String namn = reader["namn"].ToString();
   27                   System.Console.WriteLine("ID = " + id + ", namn = " + namn);
   28               }
   29               reader.Close();
   30               con.Close();
   31               System.Console.WriteLine("Tryck en tangent för att avsluta!");
   32               System.Console.ReadKey();
   33           }
   34       }
   35   }

Bild 14: Exempelprogrammet DataSetBrowser

En sak som man kan göra med ADO.NET är att koppla ihop en datakälla med en DataGridView. Exempelprogrammet DataSetBrowser kan laddas ner från Mimer, eller direkt via den här länken: DataSetBrowser.zip.

Obs! Man måste göra en del ändringar om det ska gå att kompilera i Visual Studio 2013.

DataSetBrowser

Bild 15: En enkel DataGridView

Ladda ner för Visual Studio 2013: Tisdagstest3Forms2.zip

Vi skapar en Windows Forms Application med Visual C# i Visual Studio 2013. och kopplar en DataGridView till tabellen employee i databasen dbk på basen.oru.se, via ODBC.

DataGridView


Thomas Padron-McCarthy (thomas.padron-mccarthy@oru.se), 17 februari 2015