bases dedonnees.net

27
Bases de données .NET en C# (éléments de base) (document basé sur le Framework .NET 1.1 et Visual Studio 2003) D'autres documents et exemples concernant la programmation, sur les sites: www.unvrai.com , jca.developpez.com et www.developpez.com Introduction Le but de ce document est d'offrir une base de départ permettant d'aborder plus facilement la gestion des bases de données telle qu'elle est implémentée dans l'environnement .NET. Ce document n'est, de loin, pas exhaustif et ne constitue pas un cours. Il est à voir plutôt comme un guide pour débutant, sans autre prétention que de d'illustrer l'utilisation de quelques techniques liées à la gestion des bases de données aux travers d'exemples simples. Le contenu est volontairement simplifié et l'objectif devrait être de présenter diverses situations traitées en ADO.NET. Pour mieux fixer les idées, disons que ces situations sont censées couvrir ce que l'on peut trouver dans une application autonome et typique en Access. Toutefois SQL Server sera également abordé. Afin de permettre à tout un chacun de réutiliser les exemples, ceux-ci utilisent la base de données COMPTOIR.MDB fournie avec Access (en l'occurrence Access 2003). Parmi tous les ouvrages qui abordent le sujet des bases de données dans l'environnement .NET, celui de Gérard Leblanc "C# et .NET", dont les bases de données ne représentent qu'une petite partie des domaines abordés, est l'un de ceux exposent le mieux le sujet. Ce livre a l'avantage d'être très clair au niveau technique, mais aussi pédagogique. Banalités Les bases de données constituent un des domaines les plus anciens de l'informatique et, paradoxalement, il est l'un de ceux qui change le moins; notamment en ce qui concerne les bases de données relationnelles, dont les concepts de base n'ont pas fondamentalement subi de modification depuis des décennies. Cependant les technologies qui entourent les bases de données (formats, modes d'accès…), elles, évoluent constamment, à tel point qu'on peut s'y perdre. ADO.NET est une évolution logique de diverses techniques d'accès aux données, notamment ADO, sur lesquelles nous n'allons pas revenir. On assiste depuis quelques années au passage d'applications localisées vers des applications délocalisées ou distribuées. XML prend également une importance prépondérante dans l'échange d'information. Parallèlement la frontière entre les applications traditionnelles en bases de données et les applications basées sur internet (par exemple utilisant ASP.NET) diminue. La tendance est donc, à relativement court terme, de ne plus distinguer les WebForms et les WinForms. ADO.NET propose donc un modèle qui intègre les fonctionnalités de XML et de ADO. C'est-à-dire qu'il offre des ensembles de classes, structures, interfaces, etc faisant partie intégrante du framework .NET et permettant un accès efficace et cohérent aux données. Les avantages apportés par ADO.NET sont essentiellement: la montée en charge (scalability) pose moins de problèmes qu'auparavant. Par exemple il est vraiment aisé de dédoubler un serveur web en cas de puissance de traitement accrue. Ceci est en partie dû à la possibilité de travailler en mode déconnecté avec ADO.NET et d'utiliser des caches en mémoire. l'utilisation abondante de XML, une technologie portable et standardisée permettant des échanges de données indépendants des systèmes et des plateformes. Les facilités offertes au niveau du développement. Le framework .NET, et donc les langages supportés, ont été pensés et conçus pour intégrer la gestion des bases de données. Visual Studio intègre tout ce dont le développeur a besoin, quels que soient les types d'applications. _________________________________________________________________________________________ J-C Armici - 1 -

Upload: lefuturis

Post on 18-Jun-2015

1.133 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: Bases dedonnees.net

Bases de données .NET en C# (éléments de base) (document basé sur le Framework .NET 1.1 et Visual Studio 2003) D'autres documents et exemples concernant la programmation, sur les sites: www.unvrai.com, jca.developpez.com et www.developpez.com

Introduction Le but de ce document est d'offrir une base de départ permettant d'aborder plus facilement la gestion des bases de données telle qu'elle est implémentée dans l'environnement .NET. Ce document n'est, de loin, pas exhaustif et ne constitue pas un cours. Il est à voir plutôt comme un guide pour débutant, sans autre prétention que de d'illustrer l'utilisation de quelques techniques liées à la gestion des bases de données aux travers d'exemples simples. Le contenu est volontairement simplifié et l'objectif devrait être de présenter diverses situations traitées en ADO.NET. Pour mieux fixer les idées, disons que ces situations sont censées couvrir ce que l'on peut trouver dans une application autonome et typique en Access. Toutefois SQL Server sera également abordé.

Afin de permettre à tout un chacun de réutiliser les exemples, ceux-ci utilisent la base de données COMPTOIR.MDB fournie avec Access (en l'occurrence Access 2003).

Parmi tous les ouvrages qui abordent le sujet des bases de données dans l'environnement .NET, celui de Gérard Leblanc "C# et .NET", dont les bases de données ne représentent qu'une petite partie des domaines abordés, est l'un de ceux exposent le mieux le sujet. Ce livre a l'avantage d'être très clair au niveau technique, mais aussi pédagogique.

Banalités Les bases de données constituent un des domaines les plus anciens de l'informatique et, paradoxalement, il est l'un de ceux qui change le moins; notamment en ce qui concerne les bases de données relationnelles, dont les concepts de base n'ont pas fondamentalement subi de modification depuis des décennies. Cependant les technologies qui entourent les bases de données (formats, modes d'accès…), elles, évoluent constamment, à tel point qu'on peut s'y perdre.

ADO.NET est une évolution logique de diverses techniques d'accès aux données, notamment ADO, sur lesquelles nous n'allons pas revenir. On assiste depuis quelques années au passage d'applications localisées vers des applications délocalisées ou distribuées. XML prend également une importance prépondérante dans l'échange d'information. Parallèlement la frontière entre les applications traditionnelles en bases de données et les applications basées sur internet (par exemple utilisant ASP.NET) diminue. La tendance est donc, à relativement court terme, de ne plus distinguer les WebForms et les WinForms.

ADO.NET propose donc un modèle qui intègre les fonctionnalités de XML et de ADO. C'est-à-dire qu'il offre des ensembles de classes, structures, interfaces, etc faisant partie intégrante du framework .NET et permettant un accès efficace et cohérent aux données. Les avantages apportés par ADO.NET sont essentiellement:

• la montée en charge (scalability) pose moins de problèmes qu'auparavant. Par exemple il est vraiment aisé de dédoubler un serveur web en cas de puissance de traitement accrue. Ceci est en partie dû à la possibilité de travailler en mode déconnecté avec ADO.NET et d'utiliser des caches en mémoire.

• l'utilisation abondante de XML, une technologie portable et standardisée permettant des échanges de données indépendants des systèmes et des plateformes.

• Les facilités offertes au niveau du développement. Le framework .NET, et donc les langages supportés, ont été pensés et conçus pour intégrer la gestion des bases de données. Visual Studio intègre tout ce dont le développeur a besoin, quels que soient les types d'applications.

_________________________________________________________________________________________ J-C Armici - 1 -

Page 2: Bases dedonnees.net

Il est à noter qu'ADO.NET supporte toutes sortes de de type et de formats de données:

• Des données non structurées

• Des données structurées, mais sous une forme non hiérarchique (CSV, fichiers Excel, fichiers Exchange, fichiers Active Directory, etc)

• Des données sous forme hiérarchique (XML)

• Des bases de données relationnelles (SQL Server, Oracle, Access, etc)

La compréhension de ADO.NET implique celle des modes connecté et déconnecté. En effet ADO.NET offre, en plus du mode "habituel", un mode déconnecté. La connexion à une base de données est l'opération par laquelle un programme se lie à une base de données, locale ou distante. Une connexion peut être ouverte (pendant que le programme accède aux données) ou fermée. Nous allons décrire séparément les modes connecté et déconnecté. Le choix d'un mode de travail pour une application particulière n'est pas toujours évident, chaque mode ayant des avantages et des inconvénients. Bien comprendre leurs différences devrait faciliter ce choix.

Mode connecté Dans le mode connecté, une application ouvre une connexion avec une base de données et reste connectée pendant le traitement des données. Il s'agit du mode le plus répandu et habituel. Dans ce mode, une application (client) "interagit" avec la base de données (serveur), demande des données, les modifie et les met à jour au fur et à mesure , avance enregistrement par enregistrement dans une table, etc. Il y a un lien fort, au sens interactivité du terme, entre le client et le serveur.

Mode déconnecté Dans le mode déconnecté, une application se connecte à une base de données, rapatrie une partie des données et se déconnecte de la base de données. S'il s'agit d'une opération de lecture seule (comme par exemple lors d'une consultation sur un site internet) l'opération est terminée. Si toutefois l'application doit effectuer des adjonctions ou mises à jour de données, elle doit se reconnecter à la base pour cela.

La notion importante à saisir ici est qu'une partie des données est amenée en mémoire locale du client pour y être utilisée. Cette partie des données peut être vue comme un sous-ensemble de la base de données. Il peut s'agir d'une ou plusieurs tables ou fragments de tables, avec ou sans relations. Plus généralement ce qui peut être exprimé à l'aide d'une ou plusieurs instructions SELECT (en SQL). Ce mode est particulièrement bien adapté à des applications internet dans lesquelles, par essence, on ne peut pas imposer une connexion continue à un client. Un utilisateur peut quitter un site ou fermer son browser de manière impromptue; c'est d'ailleurs le mode de fonctionnement habituel.

Avantages, inconvénients et choix du mode de travail Nous n'allons pas donner ici des recettes permettant de décider quel mode est le plus adapté à quel application. L'éventail et la diversité des applications rendent les choses plus subtiles. Et d'ailleurs il est certainement possible de concevoir une même application aussi bien en mode connecté qu'en mode déconnecté.

Un principe se dégage toutefois: pour un site internet le mode déconnecté paraît vraiment, dans le plupart de cas, le plus adéquat.

Attachons-nous maintenant à décrire le principaux avantages et inconvénients des deux modes de travail

_________________________________________________________________________________________ J-C Armici - 2 -

Page 3: Bases dedonnees.net

Avantages

Mode connecté Mode déconnecté Accès concurrent plus facile à contrôler Bien adapté aux utilisateurs mobiles

Données plus pertinentes (globalement plus souvent à jour)

Augmentation des performance et facilité de montée en charge

Utile dans les cas de consultation de données

Inconvénients

Mode connecté Mode déconnecté Nombre d'accès à la base de données et trafic réseau plus élevés

Les données sont moins souvent à jour

Nécessité de résoudre les conflits lors des mises à jour

Demande de la place mémoire côté client et plus de subtilité afin d'optimiser la quantité d'information rapatriée sur le client

Afin de faciliter la compréhension des modes connecté et déconnecté, nous allons simplifier la situation de la manière suivante:

ADO.NET

Connection

Command

DataReader

DataAdapter

DataSet

Client (WinForm, WebForm…)

Data Provider

Database

Fig. 1 Modèle ADO.NET simplifié

_________________________________________________________________________________________ J-C Armici - 3 -

Page 4: Bases dedonnees.net

Le mode connecté utilise généralement:

• Un objet Connection

• Un objet Command

• Un objet DataReader

Alors que le mode déconnecté fait appel à:

• Un objet Connection

• Un objet DataAdapter

• Un objet DataSet

Voyons plus précisément ce que recouvrent ces divers objets. Tout d'abord, la notion de fournisseur de données (data provider) recouvre un ensemble de classes spécifiques à une source de données et fonctionne uniquement avec cette source de données. Son fonctionnement est analogue à celui d'un pilote (driver) et permet d'effectuer les opérations de base: connexion à la source de données, lecture des données, mise à jour, etc. Pour le moment il existe quelques fournisseurs de données inclus dans le framework .NET, mais à terme on trouvera des fournisseurs de données pour la plupart des SGBD.

La figure 2 montre les 4 fournisseurs actuellement pris en charge sous forme de composants (et de classes):

• xxxDataAdapter

• xxxConnection

• xxxCommand

Où xxx concerne:

• OleDb, par exemple pour accéder aux bases de données Access ou SQL Server (antérieures à la version 7.0)

• Sql, pour les versions récentes de SQL Server

• Odbc, pour la plupart des SGBD pour lesquels un pilote ODBC existe. Cette possibilité élargit l'éventail des SGBD supportés

• Oracle, pour l'incontournable SGBD bien connu

Fig. 2 Les SGBD pris en charge dans Visual Studio 2003

_________________________________________________________________________________________ J-C Armici - 4 -

Page 5: Bases dedonnees.net

Comme on peut le voir sur le schéma de la figure 1, alors que les objets DataAdapter, Connection, Command et DataReader sont dépendants du fournisseur de données. Alors que la classe DataSet est indépendante du SGBD, donc de la source de données, et ses fonctionnalités sont accessibles quelle que soit l'origine des données dans une application.

Connexion à une base de données Lors de la connexion à une base de données on doit fournir une chaîne de connexion, qui n'est autre qu'une chaîne de caractère contenant des paramètres propres à chaque fournisseur de données. On peut y trouver notamment le nom du fournisseur de données, le chemin de la base de données, le nom d'utilisateur et le mot de passe, et bien d'autres paramètres. Voici un exemple permettant la connexion à une base de données Access:

string stConn = @"Data Source=""E:\.NET\JCADB\comptoir.mdb""; Provider=""Microsoft.Jet.OLEDB.4.0""; User ID=Admin"; OleDbConnection Connection = new OleDbConnection(stConn); // connexion OleDb

Bien entendu dans une application réelle le chemin de la base de données ne devrait pas figurer de manière absolue dans la chaîne de connexion, mais plutôt comme paramètre permettant d'accéder à la base de données sans devoir recompiler l'application si le chemin d'accès change. Signalons également que dans le cas ODBC le DSN (Data Source Name) constitue déjà une indirection et les paramètres de connexion sont définis au niveau du système d'exploitation. De ce fait la chaîne de connexion peut se résumer à:

string stConn = "dsn=MaBase"; OdbcConnection Connection = new OdbcConnection(stConn); // connexion Odbc

Connection Comme on peut le voir sur les fragments code précédents, la connexion à la base de données est généralement créée en spécifiant la chaîne de connexion. Dès ce moment la connexion peut être ouverte, utilisée, puis fermée.

Command L'objet Command permet d'interagir avec la base de données au travers de commandes fournies en SQL. Comme nous le verrons au travers d'exemples, il existe plusieurs variantes pour l'utilisation des commandes SQL. Voici un exemple montrant utiliser une commande SQL, ici dans le mode déconnecté avec un DataAdapter:

string stConn = @"Data Source=""E:\.NET\JCADB\comptoir.mdb""; Provider=""Microsoft.Jet.OLEDB.4.0""; User ID=Admin"; String stCmd = "SELECT Contact FROM Clients"; OleDbConnection Connection = new OleDbConnection(stConn); // connexion OleDb Connection.Open(); OleDbDataAdapter DA = new OleDbDataAdapter(stCmd, Connection);

DataReader L'objet DataReader, utilisé en mode connecté, permet d'accéder aux données d'une base de données récupérées par l'intermédiaire d'une commande SQL. Voici une illustration de l'utilisation d'un DataReader (en mode connecté)

_________________________________________________________________________________________ J-C Armici - 5 -

Page 6: Bases dedonnees.net

string stConn = @"Data Source=""E:\.NET\JCADB\comptoir.mdb""; Provider=""Microsoft.Jet.OLEDB.4.0""; User ID=Admin"; string stCmd = "SELECT Contact FROM Clients"; OleDbCommand Cmd; OleDbConnection Connection = new OleDbConnection(stConn); // connexion OleDb Connection.Open(); Cmd = new OleDbCommand (stCmd,Connection);OleDbDataReader DR = Cmd.ExecuteReader();

// commande pour cette connexion

if (DR != null) { while (DR.Read()) // boucle de lecture { listBox1.Items.Add (DR["Contact"]); // ajout dans le listBox } } Connection.Close();

Le mode connecté, avec un DataReader, permet un accès séquentiel, à sens unique (du début vers la fin) et en lecture seule. Ceci peut paraître restrictif, mais il est bien entendu possible de faire appel aux commandes SQL INSERT, UPDATE ou DELETE pour le traitement des données.

DataAdapter Un DataAdapter établit le lien entre une source de données et un DataSet. Il est donc utilisé pour remplir un DataSet ainsi que pour effectuer la mise à jour des données dans la base de données.

DataSet La classe DataSet est le composant central du mode déconnecté d'ADO.NET. Comme nous l'avons dit précédemment, un DataSet correspond à une portion de la base de données, une sorte de cache en mémoire incluant les données, les relations, les contraintes, etc. Nous en verrons l'utilisation dans divers exemples.

_________________________________________________________________________________________ J-C Armici - 6 -

Page 7: Bases dedonnees.net

Le mode déconnecté Dans cette partie nous allons voir plusieurs exemples utilisant le mode déconnecté.

Exemple 1: Dans cet exemple le programme accède à la table Clients de la base de données Access COMPTOIR.MDB en mode déconnecté. Nous devons ajouter l'accès aux namespaces System.Data et System.Data.OleDb:

using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; using System.Data.OleDb;

Fig. 3 Remplissage d'un listBox

Nous voulons simplement remplir le listBox avec la liste des noms de clients (champ Contact) de la table Clients. Pour cela nous faisons appel à un bouton dont voici le code associé:

private void buttonConnection_Click(object sender, System.EventArgs e) { string stConn = @"Data Source=""E:\.NET\JCADB\comptoir.mdb""; Provider=""Microsoft.Jet.OLEDB.4.0""; User ID=Admin"; OleDbConnection Connection = new OleDbConnection(stConn); // connexion OleDb Connection.Open(); OleDbDataAdapter DA = new OleDbDataAdapter("SELECT [Contact] FROM Clients", Connection); DataSet DS = new DataSet(); DA.Fill(DS, "Clients"); // remplissage du DataSet listBox1.DataSource = DS.Tables[0]; // remplissage du listBox listBox1.DisplayMember = "Contact"; Connection.Close(); }

_________________________________________________________________________________________ J-C Armici - 7 -

Page 8: Bases dedonnees.net

Exemple 2: Dans ce programme, en plus d'un listBox contenant les noms des Clients, nous avons ajouté trois textBox associés au Code Client, à la Société et au Contact de la table Clients.

Fig. 4 Remplissage d'un listBox et de textBox

Voici le code correspondant au clic sur le bouton "Remplir Clients":

private void buttonConnection_Click(object sender, System.EventArgs e) { string stConn = @"Data Source=""E:\.NET\JCADB\comptoir.mdb""; Provider=""Microsoft.Jet.OLEDB.4.0""; User ID=Admin"; string stCmd = "SELECT [Code client], [Société], [Contact] FROM Clients"; OleDbConnection Connection = new OleDbConnection(stConn); // connexion OleDb Connection.Open(); OleDbDataAdapter DA = new OleDbDataAdapter(stCmd, Connection); DataSet DS = new DataSet(); DA.Fill(DS, "Clients"); // remplissage du DataSet listBox1.DataSource = DS.Tables[0]; // remplissage du listBox listBox1.DisplayMember = "Contact"; textBoxCodeClient.DataBindings.Add("Text", DS.Tables[0], "Code client"); textBoxSociete.DataBindings.Add("Text", DS.Tables[0], "Société"); textBoxContact.DataBindings.Add("Text", DS.Tables[0], "Contact"); Connection.Close(); }

DataBindings est une collection contenant les caractéristiques de la liaison du composant textBox avec les données.

Remarque: Les textBox et le listBox étant liés à la même table du même DataSet par l'intermédiaire du DataAdapter DA, lorsque l'on clique sur une ligne du listBox, le contenu des 3 textBox est automatiquement synchronisé par rapport à l'enregistrement "pointé" par le listBox.

_________________________________________________________________________________________ J-C Armici - 8 -

Page 9: Bases dedonnees.net

Exemple 3: Ce programme reprend l'idée du programme précédent en modifiant l'emplacement de certaines instructions et en ajoutant la possibilité de naviguer parmi les enregistrements à l'aide de boutons

Les champs suivants ont été ajoutés dans la définition de Form1:

private CurrencyManager current; private string stConn = @"Data Source=""E:\.NET\JCADB\comptoir.mdb""; Provider=""Microsoft.Jet.OLEDB.4.0""; User ID=Admiprivate OleDbConnection Connection;

n";

La classe CurrencyManager dérive de BindingManagerBase et permet la synchronisation des contrôles dépendants dans un WinForm qui sont liés à la même source de données. Le CurrencyManager gère un pointeur vers l'élément en cour. Ceci permet non seulement de connaître la position courante, mais également de spécifier cette position.

Dans ce programme on va chercher les données directement au moment du chargement de la fenêtre (Load)

private void Form1_Load(object sender, System.EventArgs e) { Connection = new OleDbConnection(stConn); // connexion OleDb Connection.Open(); string stCmd = "SELECT [Code client], [Société], [Contact] FROM Clients"; OleDbDataAdapter DA = new OleDbDataAdapter(stCmd, Connection); DataSet DS = new DataSet(); DA.Fill(DS, "Clients"); // remplissage du DataSet listBox1.DataSource = DS.Tables[0]; // remplissage du listBox listBox1.DisplayMember = "Contact"; textBoxCodeClient.DataBindings.Add("Text", DS.Tables[0], "Code client"); textBoxSociete.DataBindings.Add("Text", DS.Tables[0], "Société"); textBoxContact.DataBindings.Add("Text", DS.Tables[0], "Contact"); current = (CurrencyManager)this.BindingContext[DS.Tables[0]]; // indicateur de // position }

La fermeture de la connexion est effectuée au moment de la fermeture de la fenêtre: private void Form1_Closed(object sender, System.EventArgs e) { Connection.Close(); }

Les événements suivants répondent au clic sur l'un des 4 boutons de déplacement: private void btnPrecedent_Click(object sender, System.EventArgs e) { current.Position--; lblCount.Text = current.Position.ToString(); } private void btnSuivant_Click(object sender, System.EventArgs e) { current.Position++; lblCount.Text = current.Position.ToString(); } private void btnPremier_Click(object sender, System.EventArgs e) { current.Position = 0; lblCount.Text = current.Position.ToString(); }

_________________________________________________________________________________________ J-C Armici - 9 -

Page 10: Bases dedonnees.net

private void btnDernier_Click(object sender, System.EventArgs e) { current.Position = current.Count - 1; lblCount.Text = current.Position.ToString(); }

A noter que lblCount est un label permettant d'afficher le numéro de l'enregistrement courant.

Tout ceci fonctionne bien, mais lorsqu'une ligne est sélectionnée dans le listBox, le numéro de l'enregistrement courant n'est pas modifié. Pour cela nous faisons appel à l'événement SelectedItemChanged du listBox afin de récupérer la position courante:

private void listBox1_SelectedIndexChanged(object sender, System.EventArgs e) { current.Position = listBox1.SelectedIndex; lblCount.Text = current.Position.ToString(); }

Fig. 5 Navigation dans les enregistrements

Exemple 4: Ce programme remplit un DataGrid avec le contenu de la table Clients, en gardant uniquement quelques colonnes. La définition de la classe Form1 est complétée par:

private string stConn = @"Data Source=""E:\.NET\JCADB\comptoir.mdb""; Provider=""Microsoft.Jet.OLEDB.4.0""; User ID=Admin"; private OleDbConnection Connection;

Et le reste du code est constitué par: private void Form1_Load(object sender, System.EventArgs e) { Connection = new OleDbConnection(stConn); // connexion OleDb string stCmd = @"SELECT [Code client], [Société], [Contact], [Ville], [Pays], [Fax] FROM Clients"; Connection.Open(); OleDbDataAdapter DA = new OleDbDataAdapter(stCmd, Connection); DataSet DS = new DataSet(); DA.Fill(DS, "Clients"); dgClients.DataSource = DS;

// remplissage du DataSet

_________________________________________________________________________________________ J-C Armici - 10 -

Page 11: Bases dedonnees.net

dgClients.DataMember = "Clients"; } private void Form1_Closed(object sender, System.EventArgs e) { Connection.Close(); }

La propriété DataSource du DataGrid permet de l'associer au DataSet contenant les enregistrements demandés et la propriété DataMember permet d'indiquer la table concernée.

L'environnement Visual Studio permet une multitude de paramétrage de propriétés concernant l'aspect du DataGrid; en voici le résultat:

Fig. 6 Utilisation d'un DataGrid

Remarque: Il est important de noter que le nom donné au contenu du DataSet peut être différent de celui de la table de la base de données: Au lieu de Clients nous pouvant utiliser un autre nom, par exemple Cli: string stCmd = @"SELECT [Code client], [Société], [Contact], [Ville], [Pays], [Fax] FROM Clients"; Connection.Open(); OleDbDataAdapter DA = new OleDbDataAdapter(stCmd, Connection); DataSet DS = new DataSet(); DA.Fill(DS, "Cli"); // remplissage du DataSet dgClients.DataSource = DS; dgClients.DataMember = "Cli";

De plus, si l'un des enregistrements est modifié dans le DataGrid:

_________________________________________________________________________________________ J-C Armici - 11 -

Page 12: Bases dedonnees.net

Fig. 7 Modification des données

On peut le valider, mais cette validation sera uniquement valable dans le DataSet. Et rappelons qu'on est en mode déconnecté et tant qu'aucune opération de mise à jour n'est effectuée sur la base de données, les modifications ne sont pas reportées. En d'autres termes, comme le DataSet réside en mémoire, après la fin de l'exécution du programme toute modification, suppression, insertion sont perdues.

Exemple 5: Ce programme est une variante du précédent permettant à l'utilisateur de spécifier où se trouve la base de données Comptoir.mdb. Pour cela on fait appel à un openFileDialog que l'on place sur la fenêtre de l'application. Afin d'extraire le nom du fichier de openFileDialog1.FileName on fait appel à la classe FileInfo définie dans System.IO:

using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; using System.Data.OleDb; using System.IO;

Au niveau de Form1 on définit également les champs: private string stConn = "Provider=Microsoft.Jet.OLEDB.4.0;User ID=Admin"; private OleDbConnection Connection;

Le reste devient: private void Form1_Load(object sender, System.EventArgs e) { string fName; openFileDialog1.Filter = "Fichiers Access (*.mdb)|*.mdb"; openFileDialog1.InitialDirectory = Application.StartupPath; openFileDialog1.Title = "Chemin de la base de données 'Comptoir.mdb'"; openFileDialog1.FileName = "comptoir.mdb"; if (openFileDialog1.ShowDialog() == DialogResult.OK) { fName = new FileInfo(openFileDialog1.FileName).Name.ToUpper(); if ( fName != "COMPTOIR.MDB") // test bonne base de données return; fName = openFileDialog1.FileName;

_________________________________________________________________________________________ J-C Armici - 12 -

Page 13: Bases dedonnees.net

stConn = "Data Source=" + fName + ";" + stConn; string stCmd = @"SELECT [Code client], [Société], [Contact], [Ville], [Pays], [Fax] FROM Clients"; Connection = new OleDbConnection(stConn); // connexion OleDb Connection.Open(); OleDbDataAdapter DA = new OleDbDataAdapter(stCmd, Connection); DataSet DS = new DataSet(); DA.Fill(DS, "Clients"); // remplissage du DataSet dgClients.DataSource = DS; dgClients.DataMember = "Clients"; } } private void Form1_Closed(object sender, System.EventArgs e) { if (Connection != null) Connection.Close(); }

La boîte de dialogue suivante apparaît au lancement de l'application:

Fig. 8 Recherche de 'Comptoir.mdb'

Exemple 6: Cet exemple montre comment utiliser un assistant de création de fenêtre liée à une base de données. Il permet de bien comprendre, au travers du code généré par l'assistant, les mécanismes du mode déconnecté lors des opérations de mise à jour, ajout ou suppression.

Voici comment procéder:

• Dans un premier temps il faut créer un nouveau projet sous forme d'une application Windows en C#

_________________________________________________________________________________________ J-C Armici - 13 -

Page 14: Bases dedonnees.net

• Dans le menu contextuel du projet (ici Access6), choisir d'ajouter un nouvel élément:

Fig. 9 Ajout d'un nouvel élément au projet

• Dans la boîte de dialogue qui apparaît, choisir "Assistant formulaire de données"

Fig. 10 Lancement de l'assistant

• Il faut ensuite suivre les étapes:

_________________________________________________________________________________________ J-C Armici - 14 -

Page 15: Bases dedonnees.net

Fig. 11 Démarrage de l'assistant

• Créer ensuite un nouveau groupe de données (ici DSClients)

Fig. 12 Choix d'un groupe de données (DataSet)

• Il faut ensuite choisir une connexion de données. Si la connexion désirée n'a encore jamais été utilisée dans un projet en Visual Studio, il faut cliquer sur le bouton "Nouvelle connexion…"

_________________________________________________________________________________________ J-C Armici - 15 -

Page 16: Bases dedonnees.net

Fig. 13 Choix d'une connexion de données

• Pour une nouvelle connexion il faut parcourir les différents onglets (essentiellement les deux premiers) de la fenêtre suivante:

Fig. 14 Spécification d'une nouvelle connexion

_________________________________________________________________________________________ J-C Armici - 16 -

Page 17: Bases dedonnees.net

• Après avoir spécifié la base de données à utiliser, on se retrouve avec la fenêtre de la figure15, et en cliquant sur le bouton "Suivant" on peut choisir une ou plusieurs tables ou vues:

Fig. 15 Choix du contenu du groupe de données

• Après avoir cliqué sur le bouton "Suivant", on obtient:

Fig. 16 Choix des champs (colonnes) à afficher

_________________________________________________________________________________________ J-C Armici - 17 -

Page 18: Bases dedonnees.net

• Après avoir cliqué sur le bouton "Suivant", on peut choisir le style d'affichage (ici un enregistrement à la fois) ainsi que la présence de divers boutons (Ajouter, Supprimer,…)

Fig. 17 Choix du style d'affichage

• Finalement on obtient la fenêtre suivante, en mode conception. On remarque les trois composants ajoutés automatiquement par l'assistant:

Fig. 18 Résultat généré par l'assistant

_________________________________________________________________________________________ J-C Armici - 18 -

Page 19: Bases dedonnees.net

• Le résultat final est simple, mais fonctionnel:

Fig. 19 Visualisation des données

Remarque: Si, à l'étape de la figure 15 nous avions choisi deux tables, par exemple Clients et Commandes, nous aurions eu droit à la fenêtre suivante permettant de spécifier la relation entre les tables afin que le code produit automatiquement par l'assistant puisse effectuer correctement la synchronisation entre table parent et table enfant.

Fig. 20 Spécification des relations

_________________________________________________________________________________________ J-C Armici - 19 -

Page 20: Bases dedonnees.net

Le résultat obtenu serait alors le suivant:

Fig. 21 Exemple de formulaire avec sous-formulaire

Voilà donc un exemple concret montrant le mode déconnecté en fonction. Il y a fonctionnellement peu de différences entre ce programme et un formulaire équivalent écrit, par exemple, en Access.

Il peut être intéressant de mettre cet assistant à contribution, au moins pour bénéficier du code généré. Quant à l'aspect un peu austère de l'interface utilisateur, le développeur aura tout loisir de le rendre plus évolué esthétiquement ou ergonomiquement. On dispose donc d'une bonne base de départ pour élaborer un vrai projet, même complexe.

Bases de données et XML XML (Extensible Markup Language) est un standard ouvert de stockage d'information, un format de fichier lisible (sous forme de texte) et simple, basé sur le principe du balisage. XML prend de plus en plus d'importance, à tel point que plusieurs SGBDR, dont SQL Server, peuvent l'utiliser comme format de stockage de données. Dans le framework .NET XML est omniprésent, explicitement ou implicitement. Dans la gestion des bases de données mettant en jeu des DataSet, XML est le support sous-jacent de la représentation des données, ce qui permet notamment une communication aisée avec les services web dont l'échange de données s'effectue précisément en XML.

_________________________________________________________________________________________ J-C Armici - 20 -

Page 21: Bases dedonnees.net

L'étude complète de XML et des éléments qui lui sont associés ne va pas être abordée ici. Bien que sa structure soit simple et facile à comprendre, il est rare que l'on doive écrire à la main du code XML; Plusieurs classes de .NET possèdent des méthodes permettant de lire et de générer facilement de données au format XML. On peut donc travailler avec XML sans vraiment en maîtriser tous les aspects.

Dans les exemples qui précèdent nous avons abordé le travail avec une base de données de manière "classique", en créant les divers objets, par exemple les DataSet, de façon dynamique. Nous allons voir maintenant comment aborder les bases de données, toujours en mode déconnecté, de manière plus "moderne" par rapport aux outils de développement existants.

Exemple 7: Cet exemple met en œuvre une approche légèrement différente pour travailler avec une table d'une base de données Access, utilisant notamment un DataSet typé.

Après avoir créé un nouveau projet C# (application Windows), un DataGrid est placé dans la fenêtre de l'application:

Fig. 22 Fenêtre principale avec un DataGrid

Après avoir fait afficher l'onglet "Explorateur de serveurs" (Ctrl-Alt-S) on peut voir une situation analogue à celle-ci:

Fig. 23 Explorateur de serveurs

_________________________________________________________________________________________ J-C Armici - 21 -

Page 22: Bases dedonnees.net

En fonction de des projets précédemment créés des connexions existantes sont montrées. Si la connexion qui nous intéresse ne figure pas dans la liste, il faut l'ajouter à l'aide d'un clic droit sur "Connexions de données", puis "Ajouter une connexion…"

Fig. 24 Ajout d'une nouvelle connexion

Dans notre cas, comme la connexion à la base de données Comptoir.mdb existe, il suffit de déployer l'arborescence jusqu'à atteindre la liste des tables de cette base de données:

Fig. 25 Liste des tables

A l'aide du glisser-déplacer (drag and drop) on amène la table Clients sur la fenêtre de l'application. Visual Studio crée alors les deux objets

Fig. 26 Connexion et adapteur

A ce stade nous allons créer un DataSet à l'aide d'un clic droit sur le projet, dans l'explorateur de projet. Dans l'option "Ajouter un nouvel élément…" nous choisissons d'ajouter un DataSet comme le montre la figure 27:

_________________________________________________________________________________________ J-C Armici - 22 -

Page 23: Bases dedonnees.net

Fig. 27 Ajout d'un DataSet

Ceci crée un nouveau fichier Dataset1.xsd dans le projet.

Fig. 28 Ajout d'un DataSet

De plus l'onglet suivant est affiché et va nous permettre de spécifier le contenu du DataSet

Fig. 29 Préparation à la spécification de la structure du DataSet

Comme l'indique la note figurant dans cette fenêtre nous allons faire un glisser-déplacer de la table Clients, depuis l'explorateur de serveurs vers cette fenêtre. Voici ce qui apparaît alors:

_________________________________________________________________________________________ J-C Armici - 23 -

Page 24: Bases dedonnees.net

Fig. 30 représentation graphique de la structure du DataSet

En réalité la structure du DataSet est décrite sous forme XML (voir figure 31), mais Visual Studio nous la montre également sous une forme plus visuelle. D'ailleurs l'onglet XML au bas de cette fenêtre montre le contenu du fichier Dataset1.xsd.

<?xml version="1.0" encoding="utf-8" ?> <xs:schema id="Dataset1" targetNamespace=http://tempuri.org/Dataset1.xsd elementFormDefault="qualified" attributeFormDefault="qualified" xmlns="http://tempuri.org/Dataset1.xsd" xmlns:mstns="http://tempuri.org/Dataset1.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> <xs:element name="Dataset1" msdata:IsDataSet="true"> <xs:complexType> <xs:choice maxOccurs="unbounded"> <xs:element name="Clients"> <xs:complexType> <xs:sequence> <xs:element name="Code_x0020_client" type="xs:string" /> <xs:element name="Société" type="xs:string" minOccurs="0" /> <xs:element name="Contact" type="xs:string" minOccurs="0" /> <xs:element name="Fonction" type="xs:string" minOccurs="0" /> <xs:element name="Adresse" type="xs:string" minOccurs="0" /> <xs:element name="Ville" type="xs:string" minOccurs="0" /> <xs:element name="Région" type="xs:string" minOccurs="0" /> <xs:element name="Code_x0020_postal" type="xs:string" minOccurs="0" /> <xs:element name="Pays" type="xs:string" minOccurs="0" /> <xs:element name="Téléphone" type="xs:string" minOccurs="0" /> <xs:element name="Fax" type="xs:string" minOccurs="0" /> </xs:sequence> </xs:complexType> </xs:element> </xs:choice> </xs:complexType> <xs:unique name="Dataset1Key1" msdata:PrimaryKey="true"> <xs:selector xpath=".//mstns:Clients" /> <xs:field xpath="mstns:Code_x0020_client" /> </xs:unique> </xs:element> </xs:schema>

Fig. 31 Structure du DataSet sous forme XML

_________________________________________________________________________________________ J-C Armici - 24 -

Page 25: Bases dedonnees.net

Nous allons maintenant générer le DataSet en sélectionnant oleDbDataAdapter1 (visible sur la figure 26) et en cliquant sur "Générer le groupe de données…" apparaissant sous la fenêtre des propriétés:

Fig. 32 Option pour générer le DataSet

Dans notre cas le DataSet existe, il s'agit de Dataset1 et nous choisissons la table Clients. A noter qu'il est également possible de choisir un nouveau DataSet.

Fig. 33 Choix du DataSet

Nous devons maintenant lier les données provenant de ce DataSet (donc de la table Clients) avec le DataGrid qui se trouver dans la fenêtre de l'application. Pour cela il faut sélectionner le DataGrid, et lui affecter une source de données (DataSource).

Fig. 34 Choix de la source de données

_________________________________________________________________________________________ J-C Armici - 25 -

Page 26: Bases dedonnees.net

En déroulant la liste concernée nous trouvons dataset11.Clients qui est précisément la source de données que nous souhaitons afficher. Les entêtes de colonnes sont alors affichés dans la grille:

Fig. 35 Grille associée au DataSet

Afin que les données puissent être affichées, il faut encore écrire le code permettant de remplir le DataSet. Pour cela, nous plaçons un bouton sur la fenêtre, sur le clic duquel nous définissons le code événementiel suivant:

private void btnCharger_Click(object sender, System.EventArgs e) { oleDbDataAdapter1.Fill (dataset11.Clients); }

Après le lancement de l'application, le clic sur le bouton permet d'afficher les données:

Fig. 36 Affichage des données

_________________________________________________________________________________________ J-C Armici - 26 -

Page 27: Bases dedonnees.net

Remarque: Le contenu de ce document se rapporte à Visual Studio 2003. L'arrivée du Framework .NET 2.0 et de Visual Studio 2005 (tous deux en version beta 2 actuellement) apporte une somme considérable de nouveautés et d'améliorations, tant au niveau du langage qu'au niveau des outils de développement. Les bases de données ne sont pas en reste.

Bien qu'en principe le nouveau cru 2005 soit compatible avec la version précédente, le mode de travail du développeur a été en partie modifié. Un nouveau document consacré aux bases de données dans l'environnement .NET devrait donc bientôt apparaître. A suivre…

_________________________________________________________________________________________ J-C Armici - 27 -