Vous êtes sur la page 1sur 20

Module : Développement d’une application Client/serveur

ADO.NET (VERSION C#)

LE MODE DECONNECTE

Travailler en mode déconnecté veut dire :


1. Récupération des données à partir de la source et en faire une copie locale. Travailler sur
des données en mémoire plutôt que directement sur un SGBD.
2. Modification des données en mode déconnecté
3. Intégration des données modifiées à la source avec éventuellement résolution des conflits
(contraintes d’intégrités)

Les objets utilises dans ce mode sont :


1. Connexion : permet d’établir la connexion
2. DataAdapter : contenant la requête Select. Il sert de liaison entre la source de données et
l’objet dataSet
3. DataSet : à la structure d’une base de données mais en local. Il peut être rempli par l’objet
DataAdapter ou bien crée indépendamment d’une source de données

DataSet

DataAdapter
Lecture de données
SelectCommand Base de
InsertCommand
données
Update command
DeleteCommand Mise à jour de données

L'OBJET DATASET
Le DataSet peut être considéré comme une base de données relationnelle quelque peu simplifiée,
constituée de tables et de leurs relations
Le principe de base du DataSet est :
 de se connecter à une source de données,
 de charger toutes ses tables avec leurs relations
 de travailler en mode déconnecté sur ces tables en mémoire
 de se reconnecter pour effectuer la mise à jour éventuelle des données.

Le DataSet est composé de deux objets principaux:


 le DataTableCollection : contient zéro ou plusieurs objets DataTable qui représentent chacunes
une table dans le DataSet
 DataRelationCollection : contient zéro ou plusieurs
DataRelations qui représentent chacunes une relation entre
deux DataTable dans le DataSet

SAIDI AHMED 1
Module : Développement d’une application Client/serveur
ADO.NET (VERSION C#)

Un objet de classe DataTable est composé en particulier des objets suivants :


 Une propriété Columns = Collection de colonnes (collection d'objets DataColumn)
 Une propriété Rows = Collection de lignes (collection d'objets DataRow)

Pour résumer, un DataSet contient pour l'essentiel deux types d'objets :


1. des objets DataTable inclus dans une DataTableCollection
2. des objets DataRelation inclus dans une DataRelationCollection

SAIDI AHMED 2
Module : Développement d’une application Client/serveur
ADO.NET (VERSION C#)
Travailler avec un DataSet
Les données du dataSet peuvent provenir soit :
1. de l’application cliente (par exemple données saisies par l’utilisateur ou calculées par
l’application, etc.)
2. d’une base de données

Avant de remplir le DataSet par les données, il faut créer sa structure


Pour créer un objet dataSet il faut instancier la classe DataSet
DataSet myDataSet= new DataSet() ;

Ou passer le nom de DataSet comme paramètre. Si vous ne faites pas, le nom de défaut de
NewDataSet sera employé.
DataSet myDataSet= new DataSet("NomDataSet");

Parmi les propriétés de l’objet DataSet


Propriété Description
Tables Collection des tables contenues dans le dataSet
Relations Collection des relations qui relient des tables du dataSet

Méthodes publiques de l’objet DataSet


Méthode Description
Valide toutes les modifications en cours (méthode existant aussi pour les objets
AcceptChanges DataTable et DataRow). Bascule toutes les lignes de toutes les tables vers l’état
‘Unchanged’
Supprime toutes les lignes de toutes les tables du DataSet. A faire avant de
Clear
recharger un DataSet.
Merge Permet de fusionner deux DataSet
Reset Réinitialise le DataSet dans son état d’origine

Méthodes publiques de l’objet DataTableCollection


Méthode Description
Add Ajoute une table à la collection des tables du DataSet

L’OBJET DATATABLE
Objet mémoire représentant une table. Elle est constituée de lignes (DataRow) et ces dernieres
sont structurées à l’aide de colonnes (DataColumn). DataSet stocke une référence à cet objet dans sa
propriété de Tables.
 Le schéma est définit dans la collection Columns
 L’intégrité des données est assurée par les objets Constraint
 Tous les objets du mode déconnecté sont déclarés dans l’espace de noms System.Data.
 Une dataTable peut etre s’instancier seule sans forcement etre rattachée à un Dataset.

Parmi les propriétés de l’objet DataTable


Propriété Description
Columns Collection des colonnes de la table
Constraints Collection des contraintes de la table
Rows Collection des lignes de la table
PrimaryKey Tableau de colonnes faisant parti de la clé primaire

SAIDI AHMED 3
Module : Développement d’une application Client/serveur
ADO.NET (VERSION C#)

 Une fois le dataset crée, on doit lui ajouter des tables et des relations.
 Pour créer un objet DataTable il faut instancier la classe DataTable puis le lier a l’objet DataSet

Creation d’une table sans paramètre.

DataTable myTable ;
myTable= new DataTable() ;

Creation d’une table mais on spécifie un nouveau nom.

DtaTable myTable ;
myTable= new DataTable("Personnes") ;

Si vous ne spécifiez pas un nom de table en ajoutant une nouvelle table à un DataSet, le nom de
défaut TableN serez assigné, où N commence à un et est incrémenté par un.

Pour rattacher une table à un DataSet , on utilse la méthode d'Add de la propriété Tables de
DataSet:

DataSet ds ;
Ds=new DataSet();
DataTable myTable =new DataTable("Personnes ") ;
ds.Tables.Add(myTable) ;

Pour retrouver la table depuis le dataset :

DataTable dt = myDataSet.Tables["Personnes "];

Vous pouvez mettre en référence une table particulière par son index dans DataSet :

DataTable myEtudiantTable = myDataSet.Tables[0];

Remarque : La référence d'index commence toujours à zéro dans un DataSet. La première table aura
l'index 0, la deuxième table aura l'index 1, et ainsi de suite.

Pour enlever une table d'un DataSet :

myDataSet.Tables.Remove("Personnes ");
//ou
DataTable myTable = myDataSet.Tables["Personnes "];
myDataSet.Tables.Remove(myTable);

Une fois la DataTable instanciée, il faut lui adjoindre des colonnes pour pouvoir la
charger en données. En effet, toutes les lignes d’une DataTable partagent la meme structure.

Événements DataTable
Semblable à beaucoup d’objets dans le .NET Framework, DataTable presente un un ensemble
d’evenement qui peut être capturé et manipulés. Nous pouvons utiliser les événements pour mettre à
jour l’interface utilisateur, ou pour valider les modifications, mises à jour ou suppressions avant qu’ils
soient dédiés.

SAIDI AHMED 4
Module : Développement d’une application Client/serveur
ADO.NET (VERSION C#)
L’objet DataTable fournit une série d’événements qui peuvent être traitées par une application.
Le tableau suivant décrit les événements DataTable.

Événement Description
ColumnChanged Se produit lorsqu’une valeur a été insérée avec succès dans une colonne.
ColumnChanging Se produit lorsqu’une valeur a été soumise pour une colonne.
RowChanged Cet événement se produit lorsqu’une ligne dans la table a été modifiée avec succès.
RowChanging Se produit lorsqu’une ligne de la table évolue.
Cet événement se produit lorsqu’une ligne dans la table a été marquée comme
RowDeleted
supprimé.
Se produit avant une ligne dans la table étant marquée comme étant supprimés. (se
RowDeleting
produit après que DataTow a été supprimé)

Exemple (voir projet DataTableEvent)


static DataTable MaTable = new DataTable("Personnes");

static void Main(string[] args)


{
MaTable.ColumnChanged += new
DataColumnChangeEventHandler(MaTable_ColumnChanged);
MaTable.ColumnChanging += new
DataColumnChangeEventHandler(MaTable_ColumnChanging);
MaTable.RowChanged += new DataRowChangeEventHandler(MaTable_RowChanged);
MaTable.RowChanging += new
DataRowChangeEventHandler(MaTable_RowChanging);
MaTable.Columns.Add(new DataColumn("Prénom"));

MaTable.Rows.Add(new object[] {"ahmed"});


MaTable.Rows.Add(new object[] { "dina" });
MaTable.Rows.Add(new object[] { "sarah" });
MaTable.Rows.Add(new object[] { "ali" });
MaTable.Rows.Add(new object[] { "amina" });

MaTable.Rows[1]["Prénom"] = "Mustapha";
Console.ReadKey();
}

static void MaTable_RowChanging(object sender, DataRowChangeEventArgs e)


{
if (e.Action != DataRowAction.Nothing)
Console.WriteLine(" RowChanged: Action = " + e.Action + ", Prenom = " +
e.Row["Prénom"]);
}

static void MaTable_RowChanged(object sender, DataRowChangeEventArgs e)


{
if (e.Action != DataRowAction.Nothing)
Console.WriteLine(" RowChanging: Action = " + e.Action + ", Prénom = " +
e.Row["Prénom"]);
}

static void MaTable_ColumnChanged(object sender, DataColumnChangeEventArgs e)


{
Console.Write(" ColumnChanged: ");

SAIDI AHMED 5
Module : Développement d’une application Client/serveur
ADO.NET (VERSION C#)
Console.Write(e.Column.ColumnName + " changed to '" + e.ProposedValue +
"'\n");
}

static void MaTable_ColumnChanging(object sender, DataColumnChangeEventArgs


e)
{
Console.Write("ColumnChanging: ");
Console.Write(e.Column.ColumnName + " equals '" + e.Row[e.Column] + "',
changing to '" + e.ProposedValue + "'\n");
}

Resultat :

L’OBJET DATACOLUMN
Élément fondamental de l’objet DataTable (contenu dans la collection Columns)
En créant une colonne, on doit spécifier plusieurs informations :
 Le nom de la colonne
 Le type de la colonne
 Les propriétés de la colonne qui sont résumées dans le tableau suivant :

Propriété Description
AllowDBNull Autorise la valeur Null
DefaultValue Valeur par défaut de la colonne
Unique Définit si les valeurs de la colonne doivent être uniques
AutoIncrement Définit si la colonne est un compteur dont la valeur s’incrémente
automatiquement
AutoIncrementSeed Valeur de départ de l’incrément
AutoIncrementStep Pas de l’incrément

Pour ajouter un objet dataColumn a l’objet dataTable, il faut instancier la classe DataColumn
puis la lier a l’objet DataTable
DataColumn col1 = new DataColumn("EleveID", typeof(int));
col1.AutoIncrement = true;
col1.AutoIncrementSeed = 1;

SAIDI AHMED 6
Module : Développement d’une application Client/serveur
ADO.NET (VERSION C#)
col1.AutoIncrementStep = 1;
Ds.Tables["EtudiantTable"].Columns.Add(col1);
Ds.Tables["EtudiantTable"].PrimaryKey = new DataColumn[] {col1};

DataColumn col2 = new DataColumn("nom", typeof(String));


col2.Unique = true;
col2.DefaultValue = "inconnu";
Ds.Tables["EtudiantTable"]).Columns.Add(col2);

DataColumn col3 = new DataColumn("DateN", typeof(DateTime));


Ds.Tables["EtudiantTable"].Columns.Add(col3);

 Le DataColumn est la clé pour créer un schéma d'un DataTable ; en ajoutant des colonnes à une
collection de DataColumn nous construisons un schéma.
 Nous pouvons accéder à ces noms de colonne en se rapportant à la propriété de colonnes du
DataTable.
 Pour regarder les noms de colonne entiers dans le DataColumnCollection, réitérer par la
collection comme vous n'importe quelle autre collection :

foreach (DataColumn MyColumn in myTable.Columns)


{
Console.WriteLine(MyColumn.ColumnName) ;
}

 Pour mettre en référence une colonne de nom, employer la propriété des colonnes du DataTable
spécifiant le nom de colonne :

DataColumn myColumn;
myColumn = myTable.Columns["nom”]

 Nous pouvons également mettre en référence la colonne par index :

DataColumn myColumn;
myColumn = myTable.Columns[0]

Exemple (voir projet Datatable)

DataTable dtable;
private void Form2_Load(object sender, EventArgs e)
{
dtable = new System.Data.DataTable();
DataColumn dcid = new System.Data.DataColumn("ID", typeof(int));
DataColumn dcnom = new System.Data.DataColumn("nom", typeof(string));
DataColumn dcage = new System.Data.DataColumn("age", typeof(int));
DataColumn dcville = new System.Data.DataColumn("ville");

SAIDI AHMED 7
Module : Développement d’une application Client/serveur
ADO.NET (VERSION C#)
dtable.Columns.Add(dcid);
dtable.Columns.Add(dcnom);
dtable.Columns.Add(dcage);
dtable.Columns.Add(dcville);

dcid.AutoIncrement = true;
dcid.AutoIncrementSeed = 11;
dcid.AutoIncrementStep = 2;
dataGridView1.DataSource = dtable;
}
private void button1_Click(object sender, EventArgs e)
{
DataRow dr = dtable.NewRow();
dr[1] = textBox1.Text;
dr[2] = int.Parse(textBox2.Text);
dr[3] = textBox3.Text;
dtable.Rows.Add(dr);
dataGridView1.DataSource = dtable;
}

L’OBJET DATAROW
Un DataRow représente une ligne de données dans la table de données. On ajoute des données à
la DataTable à l’aide d’objet DataRow.
Un objet DataRowCollection représente une collection de DataRow d’une DataTable.

Propriétés de la classe DataRow


PROPRIÉTÉ DESCRIPITION
Item Représente un élément d’une ligne (row)
ItemArray Représente toutes les valeurs d’une ligne (row)
RowState Indique l’état actuel d’une ligne (row)
Table Retourne l’objet DataTable auquel est rattaché ce row

Méthodes de classe DataRow


MÉTHODE DESCRIPTION
AcceptChanges Commente toutes les modifications apportées à DataRow
BeginEdit Commence une opération de modification sur DataRow
CancelEdit Annule la modification actuelle sur DataRow
Supprimer Supprime un objet DataRow
EndEdit Se termine la modification en cours sur DataRow
GetChildRows Retourne les lignes enfants de DataRow
GetParentRows Retours les lignes parents d’un DataRow
RejectsChanges Rejette toutes les modifications apportées depuis le dernier AcceptChanges

1. Ajout de données
Pour ajouter une ligne, il faut :
 d’abord l’instancier. : on utilise la méthode NewRow de DataTable qui crée un nouvel
objet vide de DataRow avec le même schéma que la table
 Puis il faut la valoriser c’est-à-dire on assigne les valeurs de champ,
 enfin la rattacher à la table. : à l’aide de la méthode Add de DataRowCollection
.

SAIDI AHMED 8
Module : Développement d’une application Client/serveur
ADO.NET (VERSION C#)
//ajouter des lignes
DataRow p1=myTable.NewRow() ;
p1["idp"]=1 ;
p1[" nom"]= "saidi" ;
myTable.Rows.Add(p1) ;

Il existe une autre syntaxe

myTable.Rows.Add(new object[] { 1, "saidi" });

 Vous accédez aux membres de DataRow par la colonne de la table. Une colonne sert de point de
la ligne

myTable.Rows[0] ;

 Pour regarder tous les articles dans la collection de DataRow, réitérer par la collection comme
suit :

foreach (DataRow myDataRow in myTable.Rows)


{
Console.WriteLine(myDataRow[2].ToString());
Console.WriteLine(myDataRow["Address"].ToString());
}

 Nous devons employer un nombre qui représente l'index de la valeur de colonne que nous
essayons d'accéder, ou nous pouvons employer le nom de colonne ou un objet de colonne.

int myRowNumber = 0;
int myColumnNumber = 2;
myTable.Rows[myRowNumber][myColumnNumber];

// ou...
myTable.Rows[myRowNumber]["nom"];

// ou...
DataColumn NomColumn;
NomColumn = myTable.Columns["nom"];
myTable.Rows[myRowNumbe][NomColumn];

2. Recherche de lignes
La classe DataTable possede une methode Select() que le programmeur invoque en
transmettant la clause restrictive WHERE.
String wh = "idp > 1";
DataRow[] ligne = myTable.Select(wh);

La methode Select() retourne un tableau de lignes DataRow[], lequel peut etre vide ou contenir un
ensemble multiple de rangées. Ces DataRow ont extctement la meme structure que la DataTable, mais
le programmeur à la charge de retrouver les noms des colonnes et d’éffectuer les transtypages qui
s’imposent.

if (lignes!=null)
for (int i=0 ;i<lignes.length ;i++)
{

SAIDI AHMED 9
Module : Développement d’une application Client/serveur
ADO.NET (VERSION C#)
int id;
String nom;
id=(int)lignes[i]["idp"];
nom=lignes[i]["nom"].ToString();
Console.WriteLine("id:{0} nom:{1}",id,nom);
}

3. Mise à jour d’enregistrements


Il est très facile de modifier les enregitrements contenus par une DataTables. Il suffit de
proceder comme si l’on modifiait les valeurs d’un tableau.

//premier ligne
myTable.Rows[0]["idp"]=10 ;
myTable.Rows[0]["nom"]= "derdabi";

//seconde ligne
myTable.Rows[1]["idp"]=10 ;
myTable.Rows[1]["nom"] = "Harouse";

Voici comment procéder pour la definition d’une colonne à increment automatique

colid.AutoIncrement = true;
colid.AutoIncrementSeed = 105; //point de depart de la sequence (optionnel)
colid.AutoIncrementStep = 1; // valeur d’increment (optionnel)
DataRow myrow = myTable.NewRow(); //idp est calculée
myTable.Rows.Add(myrow);//
console.WriteLine(myrow["idp"]);

4. L’état des lignes DatRow (RowState)


Les lignes d’une DatTable sont en realité visionnées. Cela signifie qu’une action de modification
est annulable en suivant diifférentes stratégies : valeur initiale, valeur par défaut, valeur précédente.
Chaque ligne posséde un marqueur de modification (on dit aussi un talon) insiquant quel est son
état : ligne inchangée, modifiee, ajouteé, suprilée, détachée (instanciée mais pas inserée dans
DataTable). Cette information est particulierement utile aux adaptateurs de données qui doivent
synchroniser la table SQL avcec DataTable.

//tester l’état des lignes


DataRow nc=client.NewRow() ;
nc["clientNom"]= "saidi" ;
Console.WriteLine(" etat : {0}",nc.RowState) ;//detached ;

Client.Rows.Add(nc) ;
Console.WriteLine(" etat : {0}",nc.Rowstate) ;//added

5. L’énumération DataRowState
l’énumération DataRowState retourne l’état actuel d’une ligne

Les membres de l’énumération DataRowState


MEMBRES DESCRIPTION
Added Ligne a été ajoutée et AcceptChanges n’a pas été appelé.
Deleted Ligne a été supprimée à l’aide de la méthode de suppression.
Detached Ligne a été créée, mais supprimé avant qu’il a été ajouté à la collection.
Modified Ligne a été modifiée, mais la méthode AcceptChanges n’est pas encore appelée.
Unchanged Ligne n’a pas changé depuis le dernier AcceptChanges est appelé.

SAIDI AHMED 10
Module : Développement d’une application Client/serveur
ADO.NET (VERSION C#)
Par exemple, la liste ci-dessous appelle RowState juste après les méthodes Delete et RejectChange.

row3.RejectChanges();
MessageBox.Show(row3.RowState.ToString());
row2.Delete();
MessageBox.Show(row2.RowState.ToString());

La Méthode RejectChanges de l’objet DataRow rejette les modifications récentes sur cette ligne.
Par exemple, si vous avez récemment ajouté myRow à DataTable, appeler la méthode RejectChanges
comme suit :

myRow. RejectChanges() ;

Ne sera pas ajouter la ligne dans Datatable.


Vous pouvez également supprimer une ligne récemment ajoutée à une DataTable en appelant la
méthode Delete de DataRow :

myRow.Delete() ;

ATTENTION : Méthode RejectChanges et delete ne peut pas travailler ensemble. si vous appliquez
les deux méthodes sur la même ligne ; RejectChanges n’ajoute pas row à la datatable.

L’ajout des lignes à un DataTable à l’aide de DataRow (voir projet Datatable)

DataTable myTable = new DataTable("etudiant");


DataColumn dtColumn;

dtColumn = new DataColumn();


dtColumn.DataType = Type.GetType("System.Int32");
dtColumn.ColumnName = "id";
dtColumn.Caption = "Etudiant ID";
dtColumn.ReadOnly = true;
dtColumn.Unique = true;

myTable.Columns.Add(dtColumn);

dtColumn = new DataColumn();


dtColumn.DataType = Type.GetType("System.String");
dtColumn.ColumnName = "Nom";
dtColumn.Caption = "Nom Etudiant";
dtColumn.AutoIncrement = false;
dtColumn.ReadOnly = false;
dtColumn.Unique = false;

myTable.Columns.Add(dtColumn);

dtColumn = new DataColumn();


dtColumn.DataType = Type.GetType("System.String");
dtColumn.ColumnName = "Adresse";
dtColumn.Caption = "Adresse";
dtColumn.ReadOnly = false;
dtColumn.Unique = false;

SAIDI AHMED 11
Module : Développement d’une application Client/serveur
ADO.NET (VERSION C#)
myTable.Columns.Add(dtColumn);

DataColumn[] PrimaryKeyColumns = new DataColumn[1];


PrimaryKeyColumns[0] = myTable.Columns["id"];
myTable.PrimaryKey = PrimaryKeyColumns;

DataSet ds = new DataSet("Etudiant");


ds.Tables.Add(myTable);

DataRow row1 = myTable.NewRow();


row1["id"] = 1001;
row1["Adresse"] = "rue 43 tanger";
row1["Nom"] = "saidi";
myTable.Rows.Add(row1);

DataRow row2 = myTable.NewRow();


row2["id"] = 1002;
row2["Nom"] = "harous";
row2["Adresse"] = "rue 60, casa";
myTable.Rows.Add(row2);

DataRow row3 = myTable.NewRow();


row3["id"] = 1003;
row3["Nom"] = "dina";
row3["Adresse"] = "rue 547 beni mkada";
myTable.Rows.Add(row3);
//row3.RejectChanges();
//row2.Delete();
dataGrid1.DataSource = ds.Tables[0];

Si vous décommentez les lignes row3. RejectChanges() et row2. Delete() à la fin de l’inscription,
indiquée dans la liste ci-dessus, la sortie ressemble à la Figure ci-dessous.

La méthode RejectChanges rejette l’ajout de la ligne 3, et la méthode Delete supprime la ligne 2.

SAIDI AHMED 12
Module : Développement d’une application Client/serveur
ADO.NET (VERSION C#)

PRIMARY KEYS(CLE PRIMAIRE)


La plupart des tables ont un certain type de colonne unique ou une combinaison des colonnes
identifiant chaque rangée des données, qui s'appellent la clé primaire.
Vous pouvez ajouter une clé primaire en plaçant la propriété d'AllowDBNull du DataColumn à faux
et la propriété unique pour rectifier :

DataColumn myColumn = myTable.Columns.Add("ID",typeof(int));


myColumn.AllowDBNull = false;
myColumn.Unique = true;;

 Ou vous pouvez spécifier la propriété de PrimaryKey de l'objet de table ; ce qui accepte un


choix d'un ou plusieurs objets de DataColumn.

DataColumn[] myColumn;
myColumn[0] = myTable.Columns["ID"];
myTable.PrimaryKey = myColumn;

 Si vous avez une clef composée faite à partir des champs multiples, vous pouvez spécifier une
combinaison des noms de colonne pour employer pour la clé primaire dans la rangée passée à la
propriété de PrimaryKey :

DataColumn[] myColumn[2] ;
myColumn|0] = myTable.Columns["ID"];
myColumn[1] = myTable.Columns["nom"];
myTable.PrimaryKey = myColumn;

Contraintes DataTable
Vous pouvez utiliser des contraintes pour appliquer des restrictions sur les données dans un
objet DataTable afin de conserver l'intégrité des données. Une contrainte est une règle automatique,
appliquée à une ou plusieurs colonnes en relation, qui détermine l'action à réaliser lorsque la valeur
d'une ligne est modifiée. Les contraintes sont appliquées lorsque la propriété
System.Data.DataSet.EnforceConstraints de l'objet DataSet a la valeur true.

Il y a deux sortes de contraintes dans ADO.NET : le ForeignKeyConstraint et UniqueConstraint.


Par défaut, ces deux contraintes sont créées automatiquement lorsque vous créez une relation entre
deux ou plusieurs tables en ajoutant un DataRelation au DataSet

 ForeignKeyConstraint.
ForeignKeyConstraint applique des règles sur la manière dont les mises à jour et les suppressions
dans les tables connexes sont propagées.
Par exemple, si une valeur d'une ligne d'une table est mise à jour ou supprimée et si cette valeur
est également utilisée dans une ou plusieurs autres tables connexes, un ForeignKeyConstraint
détermine l'action à réaliser dans les tables connexes.

Les propriétés DeleteRule et UpdateRule de la ForeignKeyConstraint définissent l'action à


entreprendre lorsque l'utilisateur tente de supprimer ou de mettre à jour une ligne dans une table
connexe.

SAIDI AHMED 13
Module : Développement d’une application Client/serveur
ADO.NET (VERSION C#)

Le tableau suivant décrit les différents paramètres disponibles pour les propriétés DeleteRule
et UpdateRule de ForeignKeyConstraint.
.
Paramètre de règle Description
Cascade Supprime ou met à jour les lignes connexes.
SetNull Définit les valeurs dans les lignes connexes sur DBNull.
SetDefault Définit les valeurs des lignes connexes sur la valeur par défaut.
None N'effectue aucune action sur les lignes connexes. Il s'agit de la valeur par
défaut

Toutefois, vous pouvez désactiver ce comportement en spécifiant createConstraints = false


lors de la création de la relation.

Exemple
DataSet ds = new DataSet();

// table parent
DataTable objCustomer = new DataTable("Customer");
objCustomer.Columns.Add("CustomerID", typeof(int));
objCustomer.Columns.Add("CustomerName", typeof(string));
ds.Tables.Add(objCustomer);

// table enfant
DataTable objOrder = new DataTable("Order");
objOrder.Columns.Add("OrderID", typeof(int));
objOrder.Columns.Add("CustomerID", typeof(int));
objOrder.Columns.Add("Product", typeof(string));
ds.Tables.Add(objOrder);
// Creation foreign key constraint et ajouter à la table enfant
ForeignKeyConstraint fk = new ForeignKeyConstraint(
"ForeignKey", objCustomer.Columns["CustomerID"],
objOrder.Columns["CustomerID"]);
objOrder.Constraints.Add(fk);
try
{
objCustomer.Rows.Add(new object[] { 1, "client1" });
objCustomer.Rows.Add(new object[] { 2, "client2" });

objOrder.Rows.Add(new object[] { 10, 1, "Digital Camara" });


objOrder.Rows.Add(new object[] { 11, 2, "Mobile" });
objOrder.Rows.Add(new object[] { 12, 1, "Bluetooth Watch" });
}
catch (Exception ex)
{
Console.WriteLine("Error: {0}\n", ex.Message);
}
Console.WriteLine("Press any key to continue.");
Console.ReadKey();

Le code précédent crée une relation étrangère entre les tables de classe et l’étudiant nommé ClassFK.

SAIDI AHMED 14
Module : Développement d’une application Client/serveur
ADO.NET (VERSION C#)
 UniqueConstraint
L'objet UniqueConstraint, qui peut être assigné soit à une seule colonne, soit à un tableau de
colonnes d'un DataTable, garantit que toutes les données des colonnes spécifiées sont uniques dans
une ligne.

Vous pouvez créer une contrainte unique pour une colonne ou un tableau de colonnes à l'aide du
constructeur UniqueConstraint. Passez l'objet UniqueConstraint résultant à la méthode Add de la
propriété Constraints de la table, qui est un ConstraintCollection.

Vous pouvez également créer une contrainte unique pour une colonne en attribuant la valeur true à
la propriété Unique de la colonne.
L'affectation de la valeur false à la propriété Unique d'une colonne unique supprime toute
contrainte existante.
L'exemple suivant créé un UniqueConstraint pour deux colonnes d'un DataTable

DataTable custTable = custDS.Tables["Customers"];


UniqueConstraint custUnique = new UniqueConstraint(new DataColumn[]
{custTable.Columns["CustomerID"],
custTable.Columns["CompanyName"]});
custDS.Tables["Customers"].Constraints.Add(custUnique);

L’OBJET DATARELATION

 Pour assurer l’intégrité des données et la cohérence, vous devez utiliser les relations entre
les deux tables. Vous obtenir cette relation en définissant une clé primaire d’une table et à
l’aide d’une clé étrangère dans l’autre table
 Toutes les relations dans un DataSet sont maintenues dans un DataRelationCollection, qui
maintient toutes les relations d'enfant et de parent.
 Dire à qu'un client a plusieurs commandes ; la table client stocke les détails du client, et la
table commandes stocke tous les détails de la commande. Pour éviter la redondance des
données, vous définissez la clé primaire de la table client comme une clé étrangère dans la
table commande. Dans cet exemple, la table client est la table parente et la table
commandes est la table enfant. La propriété ParentRelations de DataTable représente la
relation parent et ChildRelations représente la relation de l’enfant.

ATTENTION : le type de données de ces deux colonnes avec qui vous établissez le la relation entre la
table client et commande, doit être identique.

Vous pouvez également accéder cette relation via un DataSet à l’aide de sa propriété de Relations. Pour
créer une relation entre deux colonnes, vous créez deux objets DataColumn et transmettez en tant
qu’arguments de DataRelation.

DataRelation dtRelation;
DataColumn ClientCol = dtSet.Tables["Client"].Columns["id"];
DataColumn CommandCol = dtSet.Tables["Commande"].Columns["ClientId"];

dtRelation = new DataRelation("ClientCommandeRelation", CustCol, orderCol);


dtSet.Relations.add(dtRelation) ;
//ou dtSet.Tables["Commande"].ParentRelations.Add(dtRelation);

SAIDI AHMED 15
Module : Développement d’une application Client/serveur
ADO.NET (VERSION C#)
Exemple (voir projet datarelation)
DataSet ds = new DataSet("myDataSet");

// Table parents
DataTable parentTable = new DataTable("Parents");
parentTable.Columns.Add("ParentId", typeof(int));
parentTable.Columns.Add("ParentNom", typeof(string));

//Creation parents.
parentTable.Rows.Add(new object[] { 1, "Parent # 1"});
parentTable.Rows.Add(new object[] { 2, "Parent # 2" });
parentTable.Rows.Add(new object[] { 3, "Parent # 3" });
ds.Tables.Add(parentTable);

// Table Enfant
DataTable EnfantTable = new DataTable("Enfants");
EnfantTable.Columns.Add("EnfantId", typeof(int));
EnfantTable.Columns.Add("EnfantNom", typeof(string));
EnfantTable.Columns.Add("ParentId", typeof(int));

//Create Enfant.
EnfantTable.Rows.Add(new object[] { 1, "Enfant # 1", 1 });
EnfantTable.Rows.Add(new object[] { 2, "Enfant # 2", 2 });
EnfantTable.Rows.Add(new object[] { 3, "Enfant # 3", 1 });
EnfantTable.Rows.Add(new object[] { 4, "Enfant # 4", 3 });
EnfantTable.Rows.Add(new object[] { 5, "Enfant # 5", 3 });
ds.Tables.Add(EnfantTable);

// Creation relation.
DataRelation parentEnfantRelation = new DataRelation("ParentEnfant",
parentTable.Columns["ParentId"], EnfantTable.Columns["ParentId"]);
ds.Relations.Add(parentEnfantRelation);

foreach (DataRow parent in parentTable.Rows)


{
DataRow[] Enfants = parent.GetChildRows(parentEnfantRelation);
Console.WriteLine("\n{0}, à {1} Enfant",
parent["ParentNom"].ToString(), Enfants.Count<DataRow>());
foreach (DataRow Enfant in Enfants)
{
Console.WriteLine("\t{0}",
Enfant["EnfantNom"].ToString());
}
}
Console.ReadKey();

SAIDI AHMED 16
Module : Développement d’une application Client/serveur
ADO.NET (VERSION C#)

L’OBJET DATAADAPTER
Le DataAdapter est les moyens de communication physiques entre le point d'émission et
DataSet. Doté de quatre commandes ADO.Net paramétrées, l’adaptateur charge une table à l’aide de
la methode Fill et répercute sur la table SQL les modifications à l’aide de la methode Update. Cette
derniere active pour chaque ligne, l’une des trois commandes de modification, InsertCommand,
UpdateCommand ou DeleteCommand selon l’état de la ligne RowState.

 La méthode Fill ouvre la connexion à la base de donnée, fait fonctionner un DataReader


pour charger la DataTable et marque chaque ligne comme étant non modifiée, en fixant
l’état à la valeur RowState.Unchanged. la connexion est ensuite fermée et des trains de
modifications sont opérés sur la DataTable.
 La méthode Update met à jour la source de données avec les lignes qui ont été modifiées,
ajoutées ou supprimées dans le DataSet.l’adaptateur appelle la methode DataTable
.AcceptChanges ; cela signifie que toutes les lignes ont été synchronisées, elle repassent donc à
l’état RowState.Unchanged

Le schéma montre les classes qui participent aux interactions d'ensemble de données quand
vous employez le fournisseur de données

Pour construire un adaptateur, il faut definir au moins la commande de lecture SelectCommand.


string cs = "Data Source=.\\sqlexpress;Initial Catalog=Gest;Integrated
Security=True";
SqlDataAdapter da_client = new SqlDataAdapter();
da_client.SelectCommand = new SqlCommand("select * from client", new
SqlConnection(cs));

DataSet ds = new DataSet();


//lire la table
da_client.Fill(ds, "client");//crée une DataTable avec le nom logique client
//affiche des informations
Console.WriteLine("Table {0} :", ds.Tables[0].TableName);
foreach (DataColumn dc in ds.Tables[0].Columns)
{
Console.WriteLine("\t {0} :{1} ", dc.ColumnName, dc.DataType.Name);
}

SAIDI AHMED 17
Module : Développement d’une application Client/serveur
ADO.NET (VERSION C#)

Pour creer un objet DataAdapter il faut instancier l’une des deux classes suivantes :
Fournisseur Classe
OLEDB OleDbDataAdapter
SQL Server SqlDataAdapter

Parmi les methodes de l’objet DataAdapter


Méthode Description
Remplit un DataSet. Cette methode a la capacite d’ouvrir et de fermer la
Fill
connexion utilisee
Permet de récupérer les paramètres de la requête Select définie dans la
GetFillParameters
propriété SelectCommand.
Cette méthode déclenche l’envoi des modifications faites dans le DataSet vers la
Update
source de données. Elle renvoie le nombre de lignes modifiées.

Propriétés publiques
Propriété Description
Obtient ou définit une requête ou une procédure stockée pour supprimer un
DeleteCommand
enregistrement dans la source de données.
Obtient ou définit une requête ou une procédure stockée pour créer un
InsertCommand
enregistrement dans la source de données.
Obtient ou définit une requête ou une procédure stockée permettant de rapatrier
SelectCommand
des données dans le DataSet
Obtient ou définit une requête ou une procédure stockée pour mettre à jour des
UpdateCommand
enregistrements dans la source de données.

 Remplir un DataTable déjà créé

DataSet ds = new DataSet("monds");


DataTable dt = new DataTable("maTable");
DataColumn col1 =new DataColumn("num", typeof(int));
DataColumn col2 =new DataColumn("lib", typeof(string));
dt.Columns.Add(col1);
dt.Columns.Add(col2);
ds.Tables.Add(dt);
OleDbConnection cn =new OleDbConnection();
Cn.ConnectionString = "Provider=Microsoft.Jet.Oledb.4.0;Data Source =
C:\bd2.mdb";
OleDbDataAdapter da =new OleDbDataAdapter ("Select * From Table1",cn);
da.Fill(ds,"maTable");

 Créer et remplir un nouveau DataTable


Dans ce cas, c’est le dataAdapter qui cree le DataTable ainsi que sa structure.
Le DataTable passe en parametre est un DataTable inexistant qui sera cree par le DataAdapter

DataSet ds =new DataSet("monds");


OleDbConnection cn =new OleDbConnection
Cn.ConnectionString ="Provider=Microsoft.Jet.Oledb.4.0; DataSource
=C:\bd2.mdb";
OleDbDataAdapter da =new OleDbDataAdapter ("Select * From Table1",cn);
da.Fill(ds,"maTable");

SAIDI AHMED 18
Module : Développement d’une application Client/serveur
ADO.NET (VERSION C#)
 Récupérer un certain nombre d’enregistrements
Il est possible lors de l’appel de la methode Fill de specifier quelles sont les lignes de la requete a
recuperer. Pour cela, on utilise deux parametres qui sont l’indice de depart et le nombre maximal
d’enregistrements a recuperer.

OleDbDataAdapter da = new OleDbDataAdapter ("Select * From Table1",cn);


da.Fill(ds, 50, 10, "toto");
//Cet exemple permet de recuperer 10 enregistrements a partir du 50eme
enregistrement

 Remplir plusieurs DataTable simultanément


Il est egalement possible de remplir plusieurs DataTable a partir d’un seul DataAdapter en passant en
parametres plusieurs requetes separees par des points virgule.
Exemple
OleDbConnection cn =new OleDbConnection ("Provider =Microsoft.Jet.OleDb.4.0 ;
DataSource =E:\bd2.mdb");
OleDbDataAdapter da =new OleDbDataAdapter ("Select * From Client; Select *
from Produit; Select * From Commande",cn);
da.Fill(ds,"maTable1", "maTable2", "maTable3" );
//Affectation de nouveaux noms aux tables créés
ds.Tables[0].TableName = "Client";
ds.Tables[1].TableName= "Produit";
ds.Tables[2].TableName= "Commande";

Exemple DataAdapter (voir projet DataAdapter )

string str = @"Data Source=.\sqlexpress;Initial Catalog=Gest;Integrated


Security=True";
SqlConnection oCon = new SqlConnection(str);
DataSet DSet = new DataSet();
SqlDataAdapter Da = new SqlDataAdapter();
Da.SelectCommand = new SqlCommand("Select * From clients", oCon);

Da.InsertCommand = new SqlCommand("INSERT INTO clients


(cliendid,nom,compagnie,adresse,ville) VALUES
(@id,@nom,@compagnie,@adresse,@ville)", oCon);
Da.InsertCommand.Parameters.Add("@id", SqlDbType.Int, 5, "cliendid");
Da.InsertCommand.Parameters.Add("@nom", SqlDbType.NVarChar, 20, "nom");
Da.InsertCommand.Parameters.Add("@compagnie", SqlDbType.NVarChar, 20,
"compagnie");
Da.InsertCommand.Parameters.Add("@adresse", SqlDbType.NVarChar, 20,
"adresse");
Da.InsertCommand.Parameters.Add("@ville", SqlDbType.NVarChar, 20, "ville");

Da.DeleteCommand = new SqlCommand("delete from clients where cliendid=@id",


oCon);
Da.DeleteCommand.Parameters.Add("@id", SqlDbType.Int, 5, "cliendid");

Da.UpdateCommand = new SqlCommand("UPDATE clients set


nom=@nom,compagnie=@compagnie,adresse=@adresse,ville=@ville where
cliendid=@id", oCon);
Da.UpdateCommand.Parameters.Add("@id", SqlDbType.Int, 5, "cliendid");
Da.UpdateCommand.Parameters.Add("@nom", SqlDbType.NVarChar, 20, "nom");
Da.UpdateCommand.Parameters.Add("@compagnie", SqlDbType.NVarChar, 20,
"compagnie");

SAIDI AHMED 19
Module : Développement d’une application Client/serveur
ADO.NET (VERSION C#)
Da.UpdateCommand.Parameters.Add("@adresse", SqlDbType.NVarChar, 20,
"adresse");
Da.UpdateCommand.Parameters.Add("@ville", SqlDbType.NVarChar, 20, "ville");

if (DSet.Tables.Contains("clients"))
{
DSet.Tables["clients"].Clear();
}
Da.Fill(DSet, "clients");
dataGridView1.DataSource = DSet.Tables[0];

Les fournisseurs ADO.Net dispose d’une classe CommandBuilder, qui est capable de générer les
commandes SQL en question, à partir de la commande de lecture SelectCommand d’un DataAdapter :

string str = @"Data Source=.\sqlexpress;Initial Catalog=Gest;Integrated


Security=True";
SqlConnection oCon = new SqlConnection(str);
DataSet DSet = new DataSet();
SqlDataAdapter Da = new SqlDataAdapter();
Da.SelectCommand = new SqlCommand("Select * From clients", oCon);
SqlCommandBuilder cb = new SqlCommandBuilder(Da);
textBox1.Text = "Update : " + cb.GetUpdateCommand().CommandText;
textBox2.Text = "Insert : " + cb.GetInsertCommand().CommandText;
textBox3.Text = "Delete : " + cb.GetDeleteCommand().CommandText;

Da.UpdateCommand = cb.GetUpdateCommand();
Da.InsertCommand = cb.GetInsertCommand();
Da.DeleteCommand = cb.GetDeleteCommand();

SAIDI AHMED 20

Vous aimerez peut-être aussi