|
Site |
Cours VB.net |
|
|
|
Travailler avec un DataSet. |
|
|
Comment travailler (lire écrire, modifier, trier..) sur des enregistrements d'une base de données ?
Avec un DataSet.
Généralités:
Le DataSet est une représentation en mémoire des données. On charge le DataSet à partir de la base de données. Une fois chargé on peut travailler en mode déconnecté. Pour effectuer une modification, on modifie le DataSet puis on met à jour la base de donnée à partir du DataSet.
Pour remplir un DataSet il faut une Connexion puis un DataAdapter.
Il faut créer un objet Connexion puis un objet DataAdapter qui par sa propriété Fill charge le DataSet.
Les données sont extraites à l'aide de requête SQL sur l'objet Command, et on utilise un CommandBluider pour mettre à jour la base de donnée à partir du DataSet.
Le DataSet est organisé comme une base de données en mémoire, il possède:
Une propriété Tables qui contient des DataTable (Comme les tables d'un BD)
Chaque DataTable contient une propriété Columns qui contient les DataColomn (les colonnes ou champs des BD) et une propriété Rows qui contient des DataRow (Les lignes ou enregistrements des BD)

DataColumn contient des informations sur le type du champ.
DataRow permet d'accéder aux données.
Un DataSet possède aussi la propriété Constraints qui contient les Constraint (Clé primaire ou clé étrangère), et la propriété Relations qui contient les DataRelations (Relation entre les tables).
On peut créer des DataTable 'autonomes' et y mettre une table provenant d'un dataSet:
On peut créer des DataView : Vue, représentation d'une table. A partir d'une table, on peut créer plusieurs DataView avec des représentations différentes: DataView trié, DataView donc les ligne ont été filtrées (RowFilter)
Enfin une DataTable ou un DataView peut être affichés dans un contrôle (grid par exemple).
En conclusion: on connecte la base de donnée au DataSet par l'intermédiaire de Connexion et DataAdapter. Ensuite, il y a 2 manières de 'travailler':
A - On utilise les membres du DataSet pour lire ou modifier les données.
B - On lie le DataSet, une DataTable ou un DataView à un contrôle DataGrid ou ListBox..Et tout s'affiche automatiquement.
A - Utilisation du DataSet, du DataView :En pratique:
Soit une base de données Access nommée 'Nom.mdb', elle contient une table 'FichePatient' qui contient les champs (ou colonnes) 'Nom', 'Prenom'.
Je vais me connecter à cette base, extraire les enregistrements de la table 'FichePatient' et les mettre dans un DataSet. Chaque ligne du DataSet contient un patient. Je travaillerais sur ces lignes.
En tête du module, il faut importer l'espace de nom permettant d'utiliser les DataSet et OleDB.
Imports
System.DataImports System.Data.OleDb
Dans la zone Général, Déclarations du module, il faut déclarer les objets Ado:
' Déclaration Objet Connexion
Private ObjetConnection As OleDbConnection
' Déclaration Objet Commande
Private ObjetCommand As OleDbCommand
' Déclaration Objet DataAdapter
Private ObjetDataAdapter As OleDbDataAdapter
' Déclaration Objet DataSet
Private ObjetDataSet As New DataSet() 'Attention au New
'String contenant la 'Requête SQL'
Private strSql As String' Déclaration Objet DataTable
Private ObjetDataTable As DataTable
' Déclaration Objet DataRow (ligne)
Private ObjetDataRow As DataRow
'Numéro de la ligne en cours
Private RowNumber As Integer 'Numéro de l'enregistrement courant 'Paramêtres de connexion à la DB Private strConn As String 'Pour recompiler les données modifiées avant de les remettre dans le '"DataAdapter" Private ObjetCommandBuilder As OleDbCommandBuilder
'Ouverture
'Initialisation de la chaîne de paramètres pour la connexion
strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source= c:\nom.mdb;"
'Initialisation de la chaîne contenant l'instruction SQL
strSql = "SELECT FICHEPATIENT.* FROM FICHEPATIENT"
'Instanciation d'un Objet Connexion
ObjetConnection =
New OleDbConnection()'Donner à la propriété ConnectionString les paramètres de connexion
ObjetConnection.ConnectionString = strConn
'Ouvrir la connexion
ObjetConnection.Open()
'Instancier un objet Commande
ObjetCommand = New OleDbCommand(strSql)
'Instancier un objet Adapter
ObjetDataAdapter = New OleDbDataAdapter(ObjetCommand)
'initialiser l'objet Command
ObjetCommand.Connection() = ObjetConnection
'Avec l'aide de la propriété Fill du DataAdapter charger le DataSet
ObjetDataAdapter.Fill(ObjetDataSet, "FICHEPATIENT")
'Mettre dans un Objet DataTable une table du DataSet
ObjetDataTable = ObjetDataSet.Tables("FICHEPATIENT")
Ici le code est simplifié, mais dans la réalité, il est indispensable d'user de Try Catch pour capter les exceptions surtout pour ObjetConnection.Open() et pour l'update.
Les extraits (snippets) de VB 2005, donne un exemple de code plus condensé pour ouvrir un DataSet:
conn As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=AccessFile.mdb;Persist Security Info=False" Dim cmd As String = "Select * from Topics" Dim adapter As New OleDbDataAdapter(cmd, conn) Dim topics As New Data.DataSetDim
adapter.Fill(topics)
Voir un enregistrement:
Routine affichant un enregistrement:
Une TextBox nommée 'Nom' et une TextBox 'Prenom' afficheront les noms et prénom des patients.
On rappelle que RowNumber est une variable contenant le numéro de la ligne en cours ( allant de 0 à Rows.Count-1)
If
RowNumber < 0 Then Exit Sub 'Lors de l'ouverture de la BD, s'il n'y a aucun enregistrement If RowNumber > ObjetDataTable.Rows.Count - 1 Then Exit Sub' ObjetTable.Rows(Numéro de lignes).Item( Nom de colonne) donne le contenu d'un champ dans une ligne donnée
Me.Nom.Text = ObjetDataTable.Rows(RowNumber).Item("Nom").ToString
Me.Prenom.Text = ObjetDataTable.Rows(RowNumber).Item("Prenom").ToString
'Item peut avoir en paramètre le nom de la colonne ou sont index
Pour se déplacer:
Voir la ligne suivante par exemple:
RowNumber += 1 incrémente le numéro de la ligne en cours puis on affiche par:
Me.Nom.Text = ObjetDataTable.Rows(RowNumber).Item("Nom").ToString
Me.Prenom.Text = ObjetDataTable.Rows(RowNumber).Item("Prenom").ToStringRowNumber -= 1 pour la précédente.
RowNumber = 0 pour la première.
RowNumber = ObjetDataTable.Rows.Count - 1 pour la dernière.
On remarque qu' il n'y a pas d'enregistrement courant,pas de pointeur sur un enregistrement, c'est vous même qui gérez RowNumber une simple variable qui contient le numéro de l'enregistrement (l'index du DataRow) sur lequel vous travaillez.
Modifier un enregistrement:
' Extraire l'enregistrement courant
ObjetDataRow = ObjetDataSet.Tables("FICHEPATIENT").Rows(RowNumber)
'Modifier les valeurs des champs en récupérant le contenu des TextBox
ObjetDataRow("Nom") = Me.Nom.Text
ObjetDataRow("Prenom") = Me.Prenom.Text
'Pour modifier les valeurs changées dans le DataAdapter
ObjetCommandBuilder = New OleDbCommandBuilder(ObjetDataAdapter)
'Mise à jour
ObjetDataAdapter.Update(ObjetDataSet, "FICHEPATIENT")
'On vide le DataSet et on le 'recharge' de nouveau.
ObjetDataSet.Clear()
ObjetDataAdapter.Fill(ObjetDataSet, "FICHEPATIENT")
ObjetDataTable = ObjetDataSet.Tables("FICHEPATIENT")
Attention: quand la
commande Update est effectuée, si l'enregistrement ne répond pas au
spécification de la base ( doublon alors que c'est interdit, pas de valeur pour
une clé primaire, Champ ayant la valeur Null alors que c'est interdit..), une
exception est levée; si vous ne l'avez pas prévue cela plante!!
Il faut donc mettre la ligne contenant l'Update dans un Try Catch.
Ajouter un enregistrement:
ObjetDataRow = ObjetDataSet.Tables("FICHEPATIENT").NewRow()
ObjetDataRow("Nom") = Me.Nom.Text
ObjetDataRow("Prenom") = Me.Prenom.Text
ObjetDataSet.Tables("FICHEPATIENT").Rows.Add(ObjetDataRow)
'Pour modifier les valeurs changées dans le DataAdapter
ObjetCommandBuilder = New OleDbCommandBuilder(ObjetDataAdapter)
'Mise à jour
ObjetDataAdapter.Update(ObjetDataSet, "FICHEPATIENT")
'On vide le DataSet et on le 'recharge' de nouveau.
ObjetDataSet.Clear()
ObjetDataAdapter.Fill(ObjetDataSet, "FICHEPATIENT")
ObjetDataTable = ObjetDataSet.Tables("FICHEPATIENT")
il peut y avoir génération d'une exception au niveau de la ligne Update si l'ObjetDatarow présente un 'défaut', par exemple si un champ de l'ObjetDatarow a une valeur null (il n'a pas été renseigné) alors qu'il sert l'index.
Effacer l'enregistrement en cours:
ObjetDataSet.Tables("FICHEPATIENT").Rows(RowNumber).Delete()
ObjetCommandBuilder =
New OleDbCommandBuilder(objetDataAdapter)ObjetDataAdapter.Update(objetDataSet, "FICHEPATIENT")
Fermer
'Objet connectée
ObjetConnection =
NothingObjetCommand =
NothingObjetDataAdapter =
Nothing 'Objet déconnectéeObjetDataSet =
NothingObjetDataTable =
NothingObjetDataRow =
Nothing
Trier,Filtrer, rechercher.
Il existe une méthode Select pour les DataTable mais qui retourne des DataRow.
Dim expression As String = "NOM='LASSERRE'"
'expression à rechercherDim sortOrder As String = "Nom DESC"
Dim foundRows() As DataRow 'résultat dans des DataRowfoundRows = ObjetDataTable.Select(expression, sortOrder)
Dim objetDatat1 As New DataTable For Each r As DataRow In foundRowsobjetDatat1.ImportRow(r)
Next 'MsgBox(objetDatat1.Rows.Count) Dim dv As New DataView(objetDatat1)DataGrid1.DataSource = dv
Travailler sur une DataTable.
Comment ajouter une ligne (Row)
Dim LeNewRow As DataRow = ObjetDataTable.NewRow() 'On crée un DataRow
LeNewRow("NOM") = "Smith" 'On remplit la première cellule
ou LeNewRow(1) = "Smith"
ObjetDataTable.Rows.Add(LeNewRow) 'On ajoute la Row au DataTable
Utiliser un DataView.
Mais on peut aussi passer la table dans un DataView et utiliser Find Sort RowFilter sur le DataView.
Le DataView est un objet qui ressemble à une table mais qui correspond à une représentation et permet les tris ou l'utilisation d'un filtre:
'On crée un DataView, on y met une table.
Dim dv As DataView
dv.Table = ObjetDataSet.Tables("FICHEPATIENT")
ou
Dim dv As New DataView(
ObjetDataSet.Tables("FICHEPATIENT")) 'on met une table dans le dataviewensuite on peut trier le DataView:
dv.Sort = "Nom DESC" 'on trie sur le champ Nom en ordre décroissant (ASC pour un tri croissant).
On peut filtrer le DataView:
dv.RowFilter = " PreNom = 'Philippe'" 'bien respecter les '. et les majuscules/minuscules.
Le DataView ne contient plus que les rows dont la col ="Philippe". On peut afficher dans une grid.
DataGrid1.DataSource = objetDataView
On peut rechercher dans le DataView avec Find:
Dim dv As DataView
= New DataView(Mytable)
dv.Sort = "CustomerID"
' Cherche le customer named
"DUPONT" dans la première colonne
Dim i
As Integer =
dv.Find("DUPONT")
Console.WriteLine(dv(i))'Affiche sur la
console
FindRows lui retourne des DataRow
Ensuite on peut lier le DataView à une Grid.
Dim somme As Objet= ObjetDataTable.Compute("Sum (PRIX)", "Categorie=5")
On peut aussi utiliser Count() et dans le second paramètre (le filtre)) utiliser des And.
B - Remplir un DataGrid ou une ListBox avec un DataSet:
Une fois que le dataSet existe, en UNE lignede code, on peut l'afficher dans un DataGrid.(Grille avec des lignes et des colonnes comme un tableur)
DataGrid1.SetDataBinding(ObjetDataSet, "FICHEPATIENT") en VB2003 on associe le dataset à la grid
On peut aussi passer par l'intermédiaire d'une DataTable en VB 2003 et VB 2005:
Dim
matable As New DataTablematable = ObjetDataSet.Tables("FICHEPATIENT")
DataGrid1.DataSource = matable
Remplir une Listbox ligne par ligne
Dim
matable As New DataTablematable = ObjetDataSet.Tables("FICHEPATIENT")
Dim Ligne As DataRow()
For Each Ligne In Matable.Rows
List1.Items.Add(ligne.Item(" Nom "))
Next
Etudions en détails un DataSet:
Un DataSet est un groupe de données. On a vu qu'on pouvait le remplir avec une base de données mais on peut imaginer le créer de toute pièce et le remplir en créant des tables, des colonnes, des données.
Dans un DataSet on peut donc ajouter des tables, dans les tables des colonnes, des enregistrements.
L'exemple suivant crée un objet DataTable, qui
sera ajouté au DataSet.
Private myDataSet
As DataSet
' Créer une nouvelle DataTable.
Dim myDataTable As
DataTable = new DataTable("ParentTable")
' Declaration de variables DataColumn et DataRow objects.
Dim myDataColumn As DataColumn
Dim myDataRow As DataRow
' Créer un nouveau DataColumn, lui donner un DataType, un nom, divers valeurs
pour ses propriétés et l'ajouter à la DataTable.
myDataColumn = New
DataColumn()
myDataColumn.DataType = System.Type.GetType("System.Int32")
'Type de la colonne
myDataColumn.ColumnName = "id"
'Nom de la colonne
myDataColumn.ReadOnly = True
'Colonne ReadOnly
myDataColumn.Unique = True
'Evite les doublons
myDataTable.Columns.Add(myDataColumn)
' Créer une seconde column.
myDataColumn = New
DataColumn()
myDataColumn.DataType = System.Type.GetType("System.String")
myDataColumn.ColumnName = "ParentItem"
myDataColumn.AutoIncrement = False
myDataColumn.Caption = "ParentItem"
myDataColumn.ReadOnly = False
myDataColumn.Unique = False
myDataTable.Columns.Add(myDataColumn)
'La colonne id doit être une clé primaire.
Dim
PrimaryKeyColumns(0) As DataColumn
PrimaryKeyColumns(0)= myDataTable.Columns("id")
myDataTable.PrimaryKey = PrimaryKeyColumns
'la colonne peut être une colonne auto incrémentée: (la valeur du champ "CustomerID" démarre à 100 , s'incrémente de 2 automatiquement à chaque création de DataRow.
Dim MyDataColumn2 As
DataColumn = MyDataTable.Columns.Add("CustomerID", typeof(Int32))
MyDataColumn2.AutoIncrement = true
MyDataColumn2.AutoIncrementSeed = 100
MyDataColumn2.AutoIncrementStep = 2
Il est bon de la mettre en readonly
' Créer un objet DataSet
myDataSet = New
DataSet()
' Ajouter la Table au DataSet.
myDataSet.Tables.Add(myDataTable)
' Créer 3 DataRow objects (3 lignes) et les ajouter à la DatTable
Dim i As Integer
For i = 0 to 2
myDataRow = myDataTable.NewRow()
myDataRow("id") = i
myDataRow("ParentItem") = "ParentItem " + i.ToString()
myDataTable.Rows.Add(myDataRow)
Next i
End Sub
'parcourir dans la table 'ParentTable' toutes les lignes et lire le premier élément (1ère colonne)
For compteur=0 To myDataSet.Tables("ParentTable").Rows.Count -1
Element= myDataSet.Tables("ParentTable").Rows.(compteur).Item(0)
Next compteur
Travailler avec la
Base MySQL
Pour travailler sur une base MySQL lisez le très bon didacticiel MySQLDotNet (sur developpez.com bien sur)
|
|
|
|
|