I. L'objet DataSet▲
Le DataSet est un objet qui réside en mémoire et qui correspond à une copie locale des données d'une base. Il contient les tables d'une base, mais aussi les relations entre ses différentes tables et les contraintes appliquées aux données.
XML est sous .NET utilisé comme le standard de description et de persistance des données et à ce titre l'objet DataSet est représenté sous une cette forme. Les données d'un DataSet sont écrites en XML et le schéma est écrit en XSD (XML Schema Definition Language).
Comme l'objet DataSet est déconnecté de toute source de données, il peut être utilisé pour la transmission de données entre différents tiers d'une application Web (rôle assuré par les Recordsets déconnectés sous ADO), mais aussi à d'autres systèmes grâce à sa représentation XML .
Regardons plus précisément le modèle objet d'un DataSet.
Comme vous pouvez le constater, le modèle objet du DataSet s'apparente à celui d'une base de données relationnelle. Il est principalement constitué des trois collections suivantes :
- la collection « DataTableCollection » : Cette collection peut contenir de zéro à n objets de type DataTable. Chaque objet DataTable représente une table d'une source de données. Chaque DataTable est constituée d'une collection Columns et d'une collection Rows qui peuvent contenir respectivement de zéro à n objets DataRow et DataColumn ;
- la collection « DataRelationCollection » : Cette collection peut contenir de zéro à n objets de type DataRelation. Un objet DataRelation définit une relation parent-enfant entre deux tables à partir des valeurs des clés étrangères ;
- la collection « ExtendedProperties » : Cette collection correspond à un objet de type PropertyCollection qui peut contenir de zéro à n propriétés définies par un utilisateur. Cette collection peut être utilisée afin de stocker des informations personnalisées liées au DataSet utilisé (date et heure de génération des données, ordre select passé pour générer les données.).
La création d'un DataSet : La création d'une instance d'un objet DataSet se fait de la manière suivante :
'Création d'un objet DataSet
Dim
oDataSet As
New
DataSet
(
"Customers"
)
Il est possible de préciser en argument le nom du DataSet, si vous l'omettez c'est le nom « NewDataSet » qui est attribué automatiquement.
II. L'objet DataAdapter▲
Un objet DataSet doit être capable d'interagir avec une ou plusieurs sources de données. Pour réaliser cette action le framework Microsoft .Net fournit un objet nommé DataAdapter. L'objet DataAdapter sert de liaison entre un objet DataSet et une source de données. Un fournisseur de données .NET va se servir d'un objet DataAdapter pour remplir de données un DataSet puis répercuter les modifications réalisées sur une source de données. Il est possible de définir les actions à réaliser par le DataAdapter en utilisant l'une des quatre propriétés suivantes. Chaque propriété exécutera soit un ordre SQL soit une procédure stockée.
Les propriétés proposées par la classe DataAdapter sont les suivantes :
Propriété |
Description |
SelectCommand |
La propriété SelectCommand permet de récupérer des données d'une source |
InsertCommand |
La propriété InsertCommand écrit les lignes insérées d'un DataSet vers une source de données |
UpdateCommand |
La propriété UpdateCommand écrit les lignes modifiées d'un DataSet vers une source de données |
DeleteCommand |
La propriété DeleteCommand efface les lignes supprimées d'un DataSet d'une source de données |
Le schéma ci-joint présente le fonctionnement de l'objet DataAdapter :
Comme pour les objets Connection et Command, chaque fournisseur de données va proposer son objet DataAdapter spécifique. Le fournisseur de données OLEDB .NET inclut un objet OleDbDataAdapter et le fournisseur de données SQL Server .NET inclut un objet SqlDataAdapter. C'est ce dernier que nous utiliserons dans la suite de cet article.
La lecture de données et le remplissage d'un DataSet
La méthode Fill de l'objet DataAdapter permet d'extraire les données d'une source de données en exécutant la requête SQL spécifiée dans la propriété SelectCommand. Elle prend en paramètre le DataSet et le nom du DataTable à remplir avec les données retournées.
' Création d'un objet SqlDataAdapter
Dim
oSqlDataAdapter As
New
SqlDataAdapter
(
"select * from customers"
, oConnection)
Dim
oDataSet As
New
DataSet
(
"Customers"
)
oSqlDataAdapter.Fill
(
oDataSet, "Customers"
)
La mise à jour de données avec un DataAdapter et un DataSet
La méthode Update de l'objet DataAdapter permet de répercuter sur une source de données les modifications effectuées dans un DataSet. Cette méthode admet un objet DataSet qui contient les données modifiées et un objet DataTable optionnel qui contient les modifications à extraire.
oSqlDataAdapter.Update
(
oDataSet)
Mais me direz-vous comment ADO.NET assure-t-il la relation entre les données d'un DataSet et celles contenues dans une base de données ? En réalité, lorsque la méthode Update est invoquée l'objet DataAdapter analyse les modifications effectuées au niveau de la collection DataRow. En fonction des modifications rencontrées, les commandes InsertCommand, UpdateCommand et DeleteCommand sont appelées par l'objet DataAdapter.
Mettons désormais en pratique ce que nous venons d'étudier à travers un exemple. Toujours en utilisant la base d'exemple SQL2000 Microsoft nommée « NorthWind ».
Dans cet exemple, nous allons :
- récupérer la liste des catégories de la table « Categories » dans un DataSet ;
- visualiser la liste des catégories ;
- insérer de nouvelles catégories via une propriété InsertCommand ;
- actualiser le DataSet et visualiser les modifications apportées à la table « Categories ».
' Exemple d'utilisation d'un DataSet en mise à jour
Imports
System.Data.SqlClient
Imports
System.Data
Imports
System.IO
Namespace
ExempleAdoNetCSharp
' Description résumée de SqlDataSet.
Public
Class
SqlDataSet
Public
Shared
Sub
Main
(
)
Dim
strConnexion As
String
=
"Data Source=localhost; Integrated Security=SSPI;"
+
"Initial Catalog=Northwind"
Dim
strRequete As
String
=
"SELECT * FROM Categories ORDER BY CategoryID"
Try
Dim
oConnection As
New
SqlConnection
(
strConnexion)
oConnection.Open
(
)
' Chargement de la liste des catégories dans oDataSet
Dim
oSqlDataAdapter As
New
SqlDataAdapter
(
strRequete, oConnection)
Dim
oDataSet As
New
DataSet
(
"Categories"
)
oSqlDataAdapter.Fill
(
oDataSet, "Categories"
)
' Affichage du contenu de oDataSet avant insertion de données
Console.WriteLine
(
" *** Liste des catégories avant la mise à jour *** "
)
Dim
i As
Integer
For
i =
0
To
(
oDataSet.Tables
(
"Categories"
).Rows.Count
) -
1
Console.WriteLine
(
ControlChars.Tab
+
"{0}"
+
ControlChars.Tab
+
"{1}"
, oDataSet.Tables
(
"Categories"
).Rows
(
i)(
0
).ToString
(
), oDataSet.Tables
(
"Categories"
).Rows
(
i)(
1
).ToString
(
))
Next
i
Console.WriteLine
(
ControlChars.Lf
)
' Remplissage de la commande InsetCommand
oSqlDataAdapter.InsertCommand
=
New
SqlCommand
(
"INSERT INTO Categories(CategoryName, Description, Picture) Values(@CategoryName,@Description,@Picture)"
, oConnection)
oSqlDataAdapter.InsertCommand.Parameters.Add
(
"@CategoryName"
, SqlDbType.NVarChar
, 15
, "CategoryName"
)
oSqlDataAdapter.InsertCommand.Parameters.Add
(
"@Description"
, SqlDbType.NText
, 16
, "Description"
)
oSqlDataAdapter.InsertCommand.Parameters.Add
(
"@Picture"
, SqlDbType.Image
, 16
, "Picture"
)
Dim
oDataRow As
DataRow
Dim
byteArray As
Byte
(
) =
{&H0
, &H0
}
oDataRow =
oDataSet.Tables
(
"Categories"
).NewRow
(
)
oDataRow
(
"CategoryName"
) =
"Wine"
oDataRow
(
"Description"
) =
"French Wine"
oDataRow
(
"Picture"
) =
byteArray
oDataSet.Tables
(
"Categories"
).Rows.Add
(
oDataRow)
' Mise à jour de la source de données à partir du DataSet
oSqlDataAdapter.Update
(
oDataSet, "Categories"
)
' Rechargement des données de la source mise à jour
oDataSet.Clear
(
)
oSqlDataAdapter.Fill
(
oDataSet, "Categories"
)
' Affichage du contenu de oDataSet après insertion d'une ligne de données
Console.WriteLine
(
" *** Liste des catégories après la mise à jour *** "
)
Dim
i As
Integer
For
i =
0
To
(
oDataSet.Tables
(
"Categories"
).Rows.Count
) -
1
Console.WriteLine
(
ControlChars.Tab
+
"{0}"
+
ControlChars.Tab
+
"{1}"
, oDataSet.Tables
(
"Categories"
).Rows
(
i)(
0
).ToString
(
), oDataSet.Tables
(
"Categories"
).Rows
(
i)(
1
).ToString
(
))
Next
i
oConnection.Close
(
)
Catch
e As
Exception
Console.WriteLine
((
"L'erreur suivante a été rencontrée :"
+
e.Message
))
End
Try
End
Sub
'Main
End
Class
'SqlDataSet
End
Namespace
'ExempleAdoNetCSharp
III. Conclusion▲
Nous avons abordé dans cet article les objets DataSet et DataAdapter du modèle objet ADO.NET. Ces objets sont recommandés lorsqu'il est nécessaire de réaliser de nombreux traitements sur des données (modifications, filtres, tris), mais aussi pour agréger des données issues de plusieurs sources.