I. Introduction▲
Dans mon précédent article : nous avons abordé les objets Connexion, Command et DataReader qui permettent la récupération de données en mode connecté. Aujourd'hui nous allons vous présenter un nouvel objet le DataSet qui est probablement l'une des innovations les plus importantes sous ADO.NET.
II. 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.
III. 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
IV. 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.