In dit hoofdstuk leren we de niet-verbonden klassen op zich kennen, we zullen dan ook puur met deze klassen werken, en maken nog geen connectie met een database. Op deze manier leer je dat deze klassen ook nuttig kunnen zijn voor intern gegevensbeheer, en ook kunnen gebruikt worden zonder gekoppelde database.
Een DataTable aanmaken: plaats volgende code in Form1_Load:
DataTable auto = new DataTable("Auto");
// Datakolom toevoegen met alle eigenschappen
DataColumn autoid = new DataColumn("Autoid");
autoid.DataType = typeof(string);
autoid.MaxLength = 10;
autoid.Unique = true;
autoid.AllowDBNull = false;
auto.Columns.Add(autoid);
// Datakolom toevoegen met defaults
DataColumn merk = new DataColumn("Merk");
auto.Columns.Add(merk);
DataColumn bouwjaar = new DataColumn("Bouwjaar");
auto.Columns.Add(bouwjaar);
// Afgeleide kolom met een expressie
DataColumn merkjaar = new DataColumn("MerkJaar");
merkjaar.Expression = "Bouwjaar +' ' +Merk";
auto.Columns.Add(merkjaar);
Voeg nu ook een DataGridView dGVauto toe aan het Formulier
dGVauto.DataSource = auto;
auto.PrimaryKey = new DataColumn[] { autoid };
// nieuwe DataRow toevoegen
DataRow nieuweAuto = auto.NewRow();
nieuweAuto["autoid"] = "1234567";
nieuweAuto["Merk"] = "Ford";
nieuweAuto["bouwjaar"] = 2002;
auto.Rows.Add(nieuweAuto);
// Rij toevoegen via waarden
auto.Rows.Add("54321", "Peugeot", 2000);
// Rij toevoegen met methode LoadDataRow
auto.LoadDataRow(new Object[] { "9567234", "BMW", 2003 }, LoadOption.OverwriteChanges);
Extra info: een DataRow kent verschillende RowStates:
| RowState waarde | Beschrijving |
|---|---|
| Detached | De DataRow werd aangemaakt maar niet toegevoegd aan een DataTable |
| Added | De DataRow werd aangemaakt en toegevoegd aan een DataTable |
| Unchanged | De DataRow is niet veranderd sinds de laatste aanroep van de methode AcceptChanges. Wanneer de methode AcceptChanges wordt aangeroepen verandert de State van de DataRow in Unchanged. |
| Modified | De DataRow is bewerkt sinds de laatste aanroep van AcceptChanges |
| Deleted | De DataRow is verwijderd met de methode Delete van de DataRow |
Extra info: een DataRow wordt in verschillende versies bewaard in het interne geheugen:
| DataRowVersion waarde | beschrijving |
|---|---|
| Current | De huidige waarde, ook nadat veranderingen zijn aangebracht. Deze versie bestaat steeds, behalve wanneer de rij verwijderd is. |
| Default | Als de DataRowState Added of Modified is, is de Default gelijk aan de Current. Als De DataRowState Deleted is bestaat de Default niet. Als de methode BeginEdit werd uitgevoerd, dan is de versie Proposed. |
| Original | De waarde die origineel in de DataRow werd geladen, of de waarde na de laatste uitvoering van de methode AcceptChanges. |
| Proposed | De waarde wanneer de DataRow bewerkt wordt. |
auto.WriteXml(@"c:\auto.xml");
Uitvoer:
<?xml version="1.0" standalone="yes"?>
<DocumentElement>
<Auto>
<Autoid>1234567</Autoid>
<Merk>Ford</Merk>
<Bouwjaar>2002</Bouwjaar>
<MerkJaar>2002 Ford</MerkJaar>
</Auto>
<Auto>
<Autoid>54321</Autoid>
<Merk>Peugeot</Merk>
<Bouwjaar>2000</Bouwjaar>
<MerkJaar>2000 Peugeot</MerkJaar>
</Auto>
<Auto>
<Autoid>9567234</Autoid>
<Merk>BMW</Merk>
<Bouwjaar>2003</Bouwjaar>
<MerkJaar>2003 BMW</MerkJaar>
</Auto>
</DocumentElement>
// XML maken auto.TableName = "Wagen"; auto.Columns["autoid"].ColumnMapping = MappingType.Attribute; auto.Columns["merk"].ColumnMapping = MappingType.Attribute; auto.Columns["bouwjaar"].ColumnMapping = MappingType.Attribute; auto.Columns["merkjaar"].ColumnMapping = MappingType.Hidden; auto.WriteXml(@"c:\auto.xml", XmlWriteMode.WriteSchema);
Uitvoer:
<?xml version="1.0" standalone="yes"?>
<NewDataSet>
<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:MainDataTable="Wagen" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="Wagen">
<xs:complexType>
<xs:attribute name="Autoid" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="10" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="Merk" type="xs:string" />
<xs:attribute name="Bouwjaar" type="xs:string" />
<xs:attribute name="MerkJaar" msdata:ReadOnly="true" msdata:Expression="Bouwjaar +' ' +Merk" type="xs:string" use="prohibited" />
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
<xs:unique name="Constraint1" msdata:PrimaryKey="true">
<xs:selector xpath=".//Wagen" />
<xs:field xpath="@Autoid" />
</xs:unique>
</xs:element>
</xs:schema>
<Wagen Autoid="1234567" Merk="Ford" Bouwjaar="2002" />
<Wagen Autoid="54321" Merk="Peugeot" Bouwjaar="2000" />
<Wagen Autoid="9567234" Merk="BMW" Bouwjaar="2003" />
</NewDataSet>
DataView vauto = new DataView(auto); vauto.Sort = "Merk desc, Bouwjaar desc";
dGVauto.DataSource = vauto;
Merk op dat de Ford hier vervangen werd door een BMW, rijdt wat sneller :)
DataView vauto = new DataView(auto); vauto.RowFilter = "Merk like 'B%' and Bouwjaar > 2002";
Met de RowStateFilter kan je records filteren op basis van de RowState.
Voeg een nieuw formulier Form2 toe aan het project disconnected
In Program.cs zorg je ervoor dat dit nieuwe formulier getoond wordt
Code voor Form2_Load:
DataSet verkoop = new DataSet("Verkoop");
DataTable verkoper = verkoop.Tables.Add("Verkoper");
verkoper.Columns.Add("Id",typeof(Guid));
verkoper.Columns.Add("Naam",typeof(string));
verkoper.Columns.Add("Straat",typeof(string));
verkoper.Columns.Add("Nr",typeof(string));
verkoper.Columns.Add("Postcode",typeof(string));
verkoper.Columns.Add("Woonplaats",typeof(string));
verkoper.Columns.Add("Land",typeof(string));
verkoper.PrimaryKey = new DataColumn[] { verkoper.Columns["Id"] };
DataTable artikel = verkoop.Tables.Add("Artikel");
artikel.Columns.Add("Id",typeof(Guid));
artikel.Columns.Add("VerkoperId",typeof(Guid));
artikel.Columns.Add("code",typeof(string));
artikel.Columns.Add("Beschrijving",typeof(string));
artikel.Columns.Add("Aankoopprijs",typeof(decimal));
artikel.Columns.Add("Verkoopprijs",typeof(decimal));
artikel.PrimaryKey = new DataColumn[] { artikel.Columns["Id"] };
verkoop.Relations.Add("verkoper_artikel", verkoper.Columns["Id"], artikel.Columns["Verkoperid"]);
We tonen de twee tabellen inhoudsloos op het scherm:
Voeg twee DataGridViews toe aan Form2: dGVverkoper en dGVartikel
dGVverkoper.DataSource = verkoop.Tables["verkoper"]; dGVartikel.DataSource = verkoop.Tables["artikel"];
We hebben een DataSet gemaakt met twee tabellen: verkoper en artikel en een relatie tussen de twee tabellen.
De code om de tabel verkoper aan te spreken is als volgt:
DataTable verkopertabel = verkoop.Tables["Verkoper"];
Om deze reden is het beter een gespecialiseerde klasse te maken voor je DataSet die overerft van de klasse DataSet. Deze gespecialiseerde klasse kan dan een eigenschap Verkoper bevatten die als volgt benaderd kan worden:
DataTable verkopertabel = verkoop.Verkoper;
Je kan deze subklasse zelf schrijven, maar het is gewoonlijk beter om een XML schema definition (XSD)-bestand te voorzien en de afgeleide klasse door Visual Studio te laten maken. Visual Studio beschikt zelfs over een DataSet Editor waarmee je op een gebruiksvriendelijke, grafische manier een XSD-bestand kan aanmaken.
Voeg een DataSet-bestand aan je project toe: VerkoopSchema.xsd
Maak de tabellen Verkoper en Artikel aan met de DataSet Editor (rechtklikken, add...)
Maak een relatie tussen de tabellen:
Parenttabel: Verkoper(Id) / Childtable: Artikel (VerkoperId)
Foreign key constraints (cascade update, delete, geen child indien geen parent,...) kan je ook met de DataSet Editor maken.
Voeg een derde formulier Form3 toe.
Voeg twee DataGridViews toe aan Form3: dGVverkoper en dGVartikel
Voeg een DataSet toe aan Form3 (Toolbox, onderdeel Data):
Typed DataSet disconnected.VerkoopSchema, geef als Name dsVerkoop
Voorzie in Form3_Load:
dGVverkoper.DataSource = dsVerkoop.Verkoper; dGVartikel.DataSource = dsVerkoop.Artikel;
Je kan wat gegevens voorzien in de tabellen:
DataTable v = dsVerkoop.Verkoper; DataRow verkoper = v.NewRow(); Guid verkoperid = Guid.NewGuid(); verkoper["Id"] = verkoperid; verkoper["Naam"] = "Ivowinkel"; v.Rows.Add(verkoper); DataTable a = dsVerkoop.Artikel; DataRow artikel = a.NewRow(); artikel["Id"] = Guid.NewGuid(); artikel["VerkoperId"] = verkoperid; artikel["code"] = "AAA"; artikel["beschrijving"] = "Artikel A"; artikel["aankoopprijs"] = 10.0; artikel["verkoopprijs"] = 15.0; a.Rows.Add(artikel); artikel = a.NewRow(); artikel["Id"] = Guid.NewGuid(); artikel["VerkoperId"] = verkoperid; artikel["code"] = "BBB"; artikel["beschrijving"] = "Artikel B"; artikel["aankoopprijs"] = 20.0; artikel["verkoopprijs"] = 26.0; a.Rows.Add(artikel); dGVverkoper.DataSource = dsVerkoop.Verkoper; dGVartikel.DataSource = dsVerkoop.Artikel;
dsVerkoop.WriteXml(@"c:\verkoop.xml", XmlWriteMode.IgnoreSchema);
Resultaat:
<?xml version="1.0" standalone="yes"?>
<VerkoopSchema xmlns="http://tempuri.org/VerkoopSchema.xsd">
<Verkoper>
<Id>32cf9d4e-841f-421a-bbc5-c2bc0eb3715b</Id>
<Naam>Ivowinkel</Naam>
</Verkoper>
<Artikel>
<Id>9a1da7d2-9d98-4c1e-843a-5cfeaca950ed</Id>
<VerkoperId>32cf9d4e-841f-421a-bbc5-c2bc0eb3715b</VerkoperId>
<Code>AAA</Code>
<Beschrijving>Artikel A</Beschrijving>
<Aankoopprijs>10</Aankoopprijs>
<Verkoopprijs>15</Verkoopprijs>
</Artikel>
<Artikel>
<Id>79a10d2e-2642-455e-875f-3fc8fc0aa98f</Id>
<VerkoperId>32cf9d4e-841f-421a-bbc5-c2bc0eb3715b</VerkoperId>
<Code>BBB</Code>
<Beschrijving>Artikel B</Beschrijving>
<Aankoopprijs>20</Aankoopprijs>
<Verkoopprijs>26</Verkoopprijs>
</Artikel>
</VerkoopSchema>
Een DataSet retourneert met de methode CreateDataReader een DataTableReader. Bevat de DataSet meerdere tabellen, dan kan je naar de volgende tabel overgaan met de methode NextResult.
In het volgende voorbeeld geven we de namen van de verkopers en de beschrijvingen van de artikels weer in een ListBox lbArtikel.
DataTableReader dtr = dsVerkoop.CreateDataReader();
while (dtr.Read())
{
lbArtikel.Items.Add(dtr["naam"]);
}
dtr.NextResult();
while (dtr.Read())
{
lbArtikel.Items.Add(dtr["beschrijving"]);
}
| Meer tutorials: |
| leer ook: | html | | xhtml | | css | | asp | | asp.net | | c# | | ado.net | | linq | | ajax | | java | | javascript |