Delen via


Een Gegevenstoegangslaag maken (C#)

door Scott Mitchell

PDF downloaden

In deze zelfstudie beginnen we vanaf het begin en maken we de Data Access Layer (DAL), met behulp van getypte DataSets, voor toegang tot de informatie in een database.

Introductie

Als webontwikkelaars draait ons leven om het werken met gegevens. We maken databases voor het opslaan van de gegevens, code om deze op te halen en te wijzigen, en webpagina's om deze te verzamelen en samen te vatten. Dit is de eerste zelfstudie in een lange reeks waarin technieken worden verkend voor het implementeren van deze algemene patronen in ASP.NET 2.0. We beginnen met het maken van een softwarearchitectuur die bestaat uit een Data Access Layer (DAL) met behulp van Getypte DataSets, een BLL (Business Logic Layer) die aangepaste bedrijfsregels afdwingt en een presentatielaag die bestaat uit ASP.NET pagina's die een gemeenschappelijke pagina-indeling delen. Zodra dit back-end-basiswerk is gelegd, gaan we verder met rapportage, waarin wordt getoond hoe gegevens uit een webtoepassing kunnen worden weergegeven, samengevat, verzameld en gevalideerd. Deze zelfstudies zijn gericht op beknoptheid en bieden stapsgewijze instructies met tal van schermopnamen om u visueel door het proces te begeleiden. Elke zelfstudie is beschikbaar in C# en Visual Basic-versies en bevat een download van de volledige code die wordt gebruikt. (Deze eerste tutorial is behoorlijk lang, maar de rest wordt in meer hapklare brokken gepresenteerd.)

Voor deze zelfstudies gebruiken we een Microsoft SQL Server 2005 Express Edition-versie van de Northwind-database die in de map App_Data is geplaatst. Naast het databasebestand bevat de map App_Data ook de SQL-scripts voor het maken van de database, voor het geval u een andere databaseversie wilt gebruiken. Als u een andere SQL Server-versie van de Northwind-database gebruikt, moet u de instelling NORTHWNDConnectionString bijwerken in het Web.config-bestand van de toepassing. De webtoepassing is gebouwd met Visual Studio 2005 Professional Edition als een websiteproject op basis van een bestandssysteem. De zelfstudies werken allemaal even goed met de gratis versie van Visual Studio 2005, Visual Web Developer.

In deze zelfstudie beginnen we vanaf het begin en maken we de Data Access Layer (DAL), gevolgd door het maken van de Business Logic Layer (BLL) in de tweede zelfstudie en werken aan pagina-indeling en navigatie in het derde. De lessen na de derde zullen voortbouwen op de basis die in de eerste drie is gelegd. We hebben veel te maken met deze eerste zelfstudie, dus open Visual Studio en laten we aan de slag gaan.

Stap 1: een webproject maken en verbinding maken met de database

Voordat we onze Data Access Layer (DAL) kunnen maken, moeten we eerst een website maken en onze database instellen. Begin met het maken van een nieuwe ASP.NET website op basis van een bestandssysteem. Hiervoor gaat u naar het menu Bestand en kiest u Nieuwe website, waarin het dialoogvenster Nieuwe website wordt weergegeven. Kies de ASP.NET websitesjabloon, stel de vervolgkeuzelijst Locatie in op Bestandssysteem, kies een map om de website te plaatsen en stel de taal in op C#.

Maak een nieuw bestand voor de System-Based-website

Afbeelding 1: Een nieuw bestand System-Based website maken (klik hier om de volledige afbeelding weer te geven)

Hiermee maakt u een nieuwe website met een Default.aspx ASP.NET pagina en een App_Data map.

Nu de website is gemaakt, is de volgende stap het toevoegen van een verwijzing naar de database in Server Explorer van Visual Studio. Door een database toe te voegen aan Server Explorer, kunt u tabellen, opgeslagen procedures, weergaven enzovoort toevoegen vanuit Visual Studio. U kunt ook tabelgegevens weergeven of uw eigen query's handmatig of grafisch maken via de opbouwfunctie voor query's. Bovendien moeten we, wanneer we de getypte gegevenssets voor de DAL bouwen, Visual Studio laten verwijzen naar de database waaruit de getypte gegevenssets moeten worden samengesteld. Hoewel we deze verbindingsgegevens op dat moment kunnen opgeven, wordt in Visual Studio automatisch een vervolgkeuzelijst ingevuld met de databases die al zijn geregistreerd in Server Explorer.

De stappen voor het toevoegen van de Northwind-database aan Server Explorer zijn afhankelijk van het feit of u de SQL Server 2005 Express Edition-database wilt gebruiken in de map App_Data, of als u een Microsoft SQL Server 2000- of 2005-databaseserverinstallatie heeft die u wilt inzetten.

Een database gebruiken in de map App_Data

Als u geen SQL Server 2000- of 2005-databaseserver hebt om verbinding mee te maken, of als u wilt voorkomen dat u de database moet toevoegen aan een databaseserver, kunt u de SQL Server 2005 Express Edition-versie van de Northwind-database gebruiken die zich in de App_Data map van de gedownloade website bevindt (NORTHWND). MDF).

Een database die in de map App_Data wordt geplaatst, wordt automatisch toegevoegd aan Server Explorer. Ervan uitgaande dat SQL Server 2005 Express Edition op uw computer is geïnstalleerd, ziet u een knooppunt met de naam NORTHWND. MDF in Server Explorer, waarmee u de tabellen, weergaven, opgeslagen procedure, enzovoort kunt uitvouwen en verkennen (zie afbeelding 2).

De map App_Data kan ook Microsoft Access -.mdb-bestanden bevatten, die, zoals hun SQL Server-tegenhangers, automatisch worden toegevoegd aan Server Explorer. Als u geen van de SQL Server-opties wilt gebruiken, kunt u altijd northwind Traders-database en -apps installeren en in de App_Data directory neerzetten. Houd er echter rekening mee dat Access-databases niet zo uitgebreid zijn als SQL Server en niet zijn ontworpen om te worden gebruikt in websitescenario's. Bovendien maken een aantal van de meer dan 35 zelfstudies gebruik van bepaalde functies op databaseniveau die niet worden ondersteund door Access.

Verbinding maken met de database in een Microsoft SQL Server 2000- of 2005-databaseserver

U kunt ook verbinding maken met een Northwind-database die op een databaseserver is geïnstalleerd. Als de databaseserver de Northwind-database nog niet heeft geïnstalleerd, moet u deze eerst toevoegen aan de databaseserver door het installatiescript uit te voeren dat is opgenomen in de download van deze zelfstudie.

Nadat de database is geïnstalleerd, gaat u naar Server Explorer in Visual Studio, klikt u met de rechtermuisknop op het knooppunt Gegevensverbindingen en kiest u Verbinding toevoegen. Als u Server Explorer niet ziet, gaat u naar de weergave/serververkenner of drukt u op Ctrl+Alt+S. Hiermee wordt het dialoogvenster Verbinding toevoegen weergegeven, waarin u de server kunt opgeven waarmee verbinding moet worden gemaakt, de verificatiegegevens en de databasenaam. Zodra u de gegevens van de databaseverbinding hebt geconfigureerd en op de knop OK hebt geklikt, wordt de database toegevoegd als een knooppunt onder het knooppunt Gegevensverbindingen. U kunt het databaseknooppunt uitbreiden om de tabellen, weergaven, opgeslagen procedures enzovoort te verkennen.

Een verbinding toevoegen aan de Northwind-database van uw databaseserver

Afbeelding 2: Een verbinding toevoegen met de Northwind-database van uw databaseserver

Stap 2: De Gegevenstoegangslaag maken

Wanneer u met gegevens werkt, kunt u de gegevensspecifieke logica rechtstreeks insluiten in de presentatielaag (in een webtoepassing vormen de ASP.NET pagina's de presentatielaag). Dit kan de vorm hebben van het schrijven van ADO.NET-code in het codegedeelte van de ASP.NET-pagina of het gebruik van het SqlDataSource-besturingselement uit het opmaakgedeelte. In beide gevallen koppelt deze benadering de logica voor gegevenstoegang nauw aan de presentatielaag. De aanbevolen aanpak is echter om de logica voor gegevenstoegang van de presentatielaag te scheiden. Deze afzonderlijke laag wordt kort gezegd als de Data Access Layer, DAL en wordt doorgaans geïmplementeerd als een afzonderlijk Class Library-project. De voordelen van deze gelaagde architectuur zijn goed gedocumenteerd (zie de sectie Verder lezen aan het einde van deze zelfstudie voor informatie over deze voordelen) en is de benadering die we in deze reeks zullen volgen.

Alle code die specifiek is voor de onderliggende gegevensbron, zoals het maken van een verbinding met de database, het uitgeven van SELECT-, INSERT-, UPDATE- en DELETE-opdrachten , enzovoort, moet zich in de DAL bevinden. De presentatielaag mag geen verwijzingen naar dergelijke gegevenstoegangscode bevatten, maar moet in plaats daarvan aanroepen naar de DAL voor alle gegevensaanvragen. Gegevenstoegangslagen bevatten doorgaans methoden voor toegang tot de onderliggende databasegegevens. De Northwind-database bevat bijvoorbeeld tabellen Producten en Categorieën die de producten registreren die te koop zijn en de categorieën waartoe ze behoren. In onze DAL hebben we methoden zoals:

  • GetCategories(), die informatie over alle categorieën retourneert
  • GetProducts(), die informatie over alle producten retourneert
  • GetProductsByCategoryID(categoryID), waarmee alle producten worden geretourneerd die deel uitmaken van een opgegeven categorie
  • GetProductByProductID(productID), die informatie over een bepaald product retourneert

Deze methoden, wanneer deze worden aangeroepen, maken verbinding met de database, geven de juiste query uit en retourneren de resultaten. Hoe we deze resultaten presenteren, is belangrijk. Deze methoden kunnen eenvoudig een DataSet of DataReader retourneren die is gevuld door de databasequery, maar in het ideale geval moeten deze resultaten worden geretourneerd met behulp van sterk getypte objecten. Een sterk getypt object is een object waarvan het schema strikt is gedefinieerd tijdens het compileren, terwijl het tegenovergestelde, een losjes getypt object, is een object waarvan het schema pas bekend is als runtime.

De DataReader en de DataSet (standaard) zijn bijvoorbeeld losjes getypte objecten, omdat hun schema wordt gedefinieerd door de kolommen die worden geretourneerd door de databasequery die wordt gebruikt om ze te vullen. Als u toegang wilt krijgen tot een bepaalde kolom vanuit een niet strikt getype DataTable, moet u de volgende syntaxis gebruiken: DataTable.Rows[index]["columnName"]. Het losse typen van de gegevenstabel in dit voorbeeld wordt weergegeven door het feit dat we toegang moeten krijgen tot de kolomnaam met behulp van een tekenreeks of rangschikkenindex. Een sterk getypte gegevenstabel heeft daarentegen elk van de kolommen geïmplementeerd als eigenschappen, wat resulteert in code die er als volgt uitziet: DataTable. Rijen[index].columnName.

Ontwikkelaars kunnen hun eigen aangepaste zakelijke objecten maken of getypte gegevenssets gebruiken om sterk getypte objecten te retourneren. Een bedrijfsobject wordt door de ontwikkelaar geïmplementeerd als een klasse waarvan de eigenschappen doorgaans overeenkomen met de kolommen van de onderliggende databasetabel die het bedrijfsobject vertegenwoordigt. Een getypte gegevensset is een klasse die door Visual Studio wordt gegenereerd op basis van een databaseschema en waarvan de leden sterk zijn getypt volgens dit schema. De getypte gegevensset zelf bestaat uit klassen waarmee de klassen ADO.NET DataSet, DataTable en DataRow worden uitgebreid. Naast sterk getypte gegevenstabellen bevatten getypte gegevenssets nu ook TableAdapters, die klassen zijn met methoden voor het vullen van de DataSet-gegevenstabellen en het doorgeven van wijzigingen in de DataTables terug naar de database.

Opmerking

Voor meer informatie over de voor- en nadelen van het gebruik van getypte gegevenssets versus aangepaste zakelijke objecten raadpleegt u Onderdelen van gegevenslaag ontwerpen en Gegevens doorgeven via lagen.

We zullen gebruikmaken van sterk getypeerde DataSets voor de structuur van deze tutorials. Afbeelding 3 illustreert de werkstroom tussen de verschillende lagen van een toepassing die gebruikmaakt van getypte gegevenssets.

Alle Data Access Code wordt toegewezen aan de DAL

Afbeelding 3: Alle Data Access-code wordt gedegradeerd naar de DAL (klik om de afbeelding volledig weer te geven)

Een getypte gegevensset en tabeladapter maken

Om te beginnen met het maken van onze DAL, voegen we eerst een Getypte DataSet toe aan ons project. Hiervoor klikt u met de rechtermuisknop op het projectknooppunt in Solution Explorer en kiest u Een nieuw item toevoegen. Selecteer de optie DataSet in de lijst met sjablonen en geef deze de naam Northwind.xsd.

Kies ervoor om een nieuwe gegevensset toe te voegen aan uw project

Afbeelding 4: Kies ervoor om een nieuwe gegevensset toe te voegen aan uw project (klik om de afbeelding op volledige grootte weer te geven)

Nadat u op Toevoegen hebt geklikt, kiest u Ja wanneer u wordt gevraagd om de DataSet toe te voegen aan de map App_Code . De ontwerper voor de getypte gegevensset wordt vervolgens weergegeven en de configuratiewizard van de TableAdapter wordt gestart, zodat u uw eerste TableAdapter kunt toevoegen aan de getypte gegevensset.

Een getypeerde gegevensset fungeert als een sterk getypeerde verzameling gegevens; het bestaat uit sterk getypte DataTable-exemplaren, die elk op hun beurt bestaan uit sterk getypte DataRow-exemplaren. We maken een sterk getypte gegevenstabel voor elk van de onderliggende databasetabellen waarmee we moeten werken in deze reeks zelfstudies. Laten we beginnen met het maken van een gegevenstabel voor de tabel Producten .

Houd er rekening mee dat sterk getypte gegevenstabellen geen informatie bevatten over het openen van gegevens uit de onderliggende databasetabel. Om de gegevens op te halen om de DataTable te vullen, gebruiken we een TableAdapter-klasse, die fungeert als onze Data Access-laag. Voor onze Products DataTable bevat de TableAdapter de methoden GetProducts(), GetProductByCategoryID(categoryID), enzovoort die we vanuit de presentatielaag zullen aanroepen. De rol van de DataTable is om te fungeren als de sterk getype objecten die worden gebruikt om gegevens tussen de lagen te transporteren.

De wizard TableAdapter-configuratie begint met het vragen om te selecteren met welke database u wilt werken. In de vervolgkeuzelijst worden die databases weergegeven in Server Explorer. Als u de Northwind-database niet hebt toegevoegd aan Server Explorer, kunt u op dit moment op de knop Nieuwe verbinding klikken om dit te doen.

Kies de Northwind-database in de Drop-Down-lijst

Afbeelding 5: Kies de Northwind-database in de Drop-Down lijst (klik hier om de volledige afbeelding weer te geven)

Nadat u de database hebt geselecteerd en op Volgende hebt geklikt, wordt u gevraagd of u de verbindingsreeks wilt opslaan in het Web.config bestand. Door de verbindingsreeks op te slaan, vermijdt u dat deze in de TableAdapter-klassen is vastgelegd. Dit vereenvoudigt dingen als de gegevens van de verbindingsreeks in de toekomst veranderen. Als u ervoor kiest om de verbindingsreeks op te slaan in het configuratiebestand, wordt deze in de <sectie connectionStrings> geplaatst, die optioneel kan worden versleuteld voor verbeterde beveiliging of later kan worden gewijzigd via de nieuwe eigenschappenpagina van ASP.NET 2.0 in het IIS GUI Admin Tool, wat ideaal is voor beheerders.

Sla de verbindingsreeks op in Web.config

Afbeelding 6: Sla de verbindingsreeks op Web.config (klik om de afbeelding op volledige grootte weer te geven)

Vervolgens moeten we het schema voor de eerste sterk getypte gegevenstabel definiëren en de eerste methode opgeven die onze TableAdapter moet gebruiken bij het invullen van de sterk getypte DataSet. Deze twee stappen worden gelijktijdig uitgevoerd door een query te maken die de kolommen retourneert uit de tabel die we in de gegevenstabel willen weergeven. Aan het einde van de wizard geven we een methodenaam aan deze query. Zodra dat is bereikt, kan deze methode worden aangeroepen vanuit de presentatielaag. De methode voert de gedefinieerde query uit en vult een sterk getypte gegevenstabel.

Om aan de slag te gaan met het definiëren van de SQL-query, moeten we eerst aangeven hoe de TableAdapter de query moet uitgeven. We kunnen een ad-hoc SQL-instructie gebruiken, een nieuwe opgeslagen procedure maken of een bestaande opgeslagen procedure gebruiken. Voor deze handleidingen gebruiken we ad-hoc SQL-instructies.

Een query uitvoeren op de gegevens met behulp van een ad-hoc SQL-instructie

Afbeelding 7: Een query uitvoeren op de gegevens met behulp van een ad-hoc SQL-instructie (klik om de afbeelding op volledige grootte weer te geven)

Op dit moment kunnen we de SQL-query handmatig typen. Bij het maken van de eerste methode in tableAdapter wilt u meestal dat de query de kolommen retourneert die moeten worden uitgedrukt in de bijbehorende gegevenstabel. We kunnen dit doen door een query te maken die alle kolommen en alle rijen uit de tabel Producten retourneert:

Voer de SQL-query in het tekstvak in

Afbeelding 8: Voer de SQL-query in het tekstvak in (klik om de afbeelding op volledige grootte weer te geven)

U kunt ook de opbouwfunctie voor query's gebruiken en de query grafisch samenstellen, zoals wordt weergegeven in afbeelding 9.

De query grafisch maken via de Query-editor

Afbeelding 9: Maak de query grafisch via de queryeditor (klik hier om de volledige afbeelding weer te geven)

Nadat u de query hebt gemaakt, maar voordat u naar het volgende scherm gaat, klikt u op de knop Geavanceerde opties. In websiteprojecten is 'Instructies voor invoegen, bijwerken en verwijderen genereren' de enige geavanceerde optie die standaard is geselecteerd; Als u deze wizard uitvoert vanuit een klassebibliotheek of een Windows-project, wordt ook de optie Optimistische gelijktijdigheid gebruiken geselecteerd. Laat de optie "Optimistische gelijktijdigheid gebruiken" voorlopig niet aangevinkt. In toekomstige zelfstudies wordt optimistische gelijktijdigheid onderzocht.

Selecteer alleen de optie om Invoegen, Bijwerken en Verwijderen te genereren

Afbeelding 10: Selecteer alleen de optie Om invoeg-, bijwerk- en verwijderinstructies te genereren (klik hier om de volledige afbeelding weer te geven)

Nadat u de geavanceerde opties hebt gecontroleerd, klikt u op Volgende om door te gaan naar het laatste scherm. Hier wordt gevraagd om te selecteren welke methoden u aan de TableAdapter wilt toevoegen. Er zijn twee patronen voor het vullen van gegevens:

  • Vul een DataTable met deze aanpak wordt een methode gecreëerd die een DataTable als parameter neemt en deze invult op basis van de resultaten van de query. De ADO.NET DataAdapter-klasse implementeert dit patroon bijvoorbeeld met de fill() -methode.
  • Een gegevenstabel retourneren: bij deze benadering creëert en vult de methode automatisch de gegevenstabel voor u in en retourneert deze als de retourwaarde van de methode.

U kunt de TableAdapter een of beide van deze patronen laten implementeren. U kunt ook de naam van de hier opgegeven methoden wijzigen. Laten we beide selectievakjes aanvinken, ook al gebruiken we alleen het laatste patroon in deze tutorials. Laten we ook de naam van de vrij algemene GetData-methode wijzigen in GetProducts.

Als dit is ingeschakeld, maakt u met het laatste selectievakje GenerateDBDirectMethods de methoden Insert(),Update()en Delete() voor de TableAdapter. Als u deze optie uitgeschakeld laat, moeten alle updates worden uitgevoerd via de enige Update() -methode van TableAdapter, die de getypte gegevensset, een gegevenstabel, één DataRow of een matrix van DataRows gebruikt. (Als u de optie 'Instructies invoegen, bijwerken en verwijderen genereren' uit de geavanceerde eigenschappen in afbeelding 9 hebt uitgeschakeld, heeft dit selectievakje geen effect.) Laten we dit selectievakje ingeschakeld laten.

De methodenaam wijzigen van GetData in GetProducts

Afbeelding 11: Wijzig de methodenaam van GetData in GetProducts (klik om de afbeelding op volledige grootte weer te geven)

Voltooi de wizard door op Voltooien te klikken. Nadat de wizard is gesloten, worden we teruggezet naar de DataSet Designer, waarin de gegevenstabel wordt weergegeven die we zojuist hebben gemaakt. U kunt de lijst met kolommen in de gegevenstabel Producten (ProductID, ProductName, enzovoort) zien, evenals de methoden van de ProductsTableAdapter (Fill() en GetProducts()).

De Products DataTable en ProductsTableAdapter zijn toegevoegd aan de getypte dataset

Afbeelding 12: De Products DataTable en ProductsTableAdapter zijn toegevoegd aan de getypte gegevensset (klik om de afbeelding volledig weer te geven)

Op dit moment hebben we een Getypeerde DataSet met één DataTable (Northwind.Products) en een sterk getypeerde DataAdapter-klasse (NorthwindTableAdapters.ProductsTableAdapter) met een GetProducts() -methode. Deze objecten kunnen worden gebruikt voor toegang tot een lijst met alle producten uit code, zoals:

NorthwindTableAdapters.ProductsTableAdapter productsAdapter =
    new NorthwindTableAdapters.ProductsTableAdapter();
Northwind.ProductsDataTable products;
products = productsAdapter.GetProducts();
foreach (Northwind.ProductsRow productRow in products)
    Response.Write("Product: " + productRow.ProductName + "<br />");

Voor deze code hoeven we geen code te schrijven die specifiek is voor gegevenstoegang. We hoeven geen ADO.NET klassen te instantiëren, we hoeven niet te verwijzen naar verbindingsreeksen, SQL-query's of opgeslagen procedures. In plaats daarvan zorgt de TableAdapter voor de toegangscode tot gegevens op laag niveau.

Elk object dat in dit voorbeeld wordt gebruikt, is ook sterk getypt, waardoor Visual Studio IntelliSense en typecontrole tijdens compilatietijd kan bieden. Het beste van alles is dat de DataTables die door de TableAdapter worden geretourneerd, kunnen worden gebonden aan ASP.NET webbesturingselementen, zoals de GridView, DetailsView, DropDownList, CheckBoxList en verschillende andere. Het volgende voorbeeld illustreert het binden van de gegevenstabel die door de methode GetProducts() wordt geretourneerd aan een GridView in slechts een scant drie coderegels binnen de Page_Load gebeurtenis-handler.

AllProducts.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="AllProducts.aspx.cs"
    Inherits="AllProducts" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>View All Products in a GridView</title>
    <link href="Styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <h2>
            All Products</h2>
        <p>
            <asp:GridView ID="GridView1" runat="server"
             CssClass="DataWebControlStyle">
               <HeaderStyle CssClass="HeaderStyle" />
               <AlternatingRowStyle CssClass="AlternatingRowStyle" />
            </asp:GridView>
             </p>
    </div>
    </form>
</body>
</html>

AllProducts.aspx.cs

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using NorthwindTableAdapters;
public partial class AllProducts : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        ProductsTableAdapter productsAdapter = new
         ProductsTableAdapter();
        GridView1.DataSource = productsAdapter.GetProducts();
        GridView1.DataBind();
    }
}

De lijst met producten wordt weergegeven in een GridView

Afbeelding 13: De lijst met producten wordt weergegeven in een rasterweergave (klik om de afbeelding op volledige grootte weer te geven)

Hoewel we in dit voorbeeld drie regels code moeten schrijven in de Page_Load gebeurtenis-handler van onze ASP.NET pagina, gaan we in toekomstige zelfstudies onderzoeken hoe we de ObjectDataSource gebruiken om de gegevens declaratief op te halen uit de DAL. Met de ObjectDataSource hoeven we geen code te schrijven en krijgen we ook ondersteuning voor paging en sortering.

Stap 3: Geparameteriseerde methoden toevoegen aan de Gegevenstoegangslaag

Op dit moment heeft onze klasse ProductsTableAdapter maar één methode, GetProducts(), die alle producten in de database retourneert. Hoewel het werken met alle producten zeker nuttig is, zijn er momenten waarop we informatie willen ophalen over een specifiek product of alle producten die deel uitmaken van een bepaalde categorie. Om dergelijke functionaliteit toe te voegen aan onze Data Access-laag, kunnen we geparameteriseerde methoden toevoegen aan de TableAdapter.

Laten we de methode GetProductsByCategoryID(categoryID) toevoegen. Als u een nieuwe methode aan de DAL wilt toevoegen, gaat u terug naar datasetontwerper, klikt u met de rechtermuisknop in de sectie ProductsTableAdapter en kiest u Query toevoegen.

Right-Click op de TableAdapter en Kies Query toevoegen

Afbeelding 14: Right-Click op de TableAdapter en Kies Query toevoegen

We worden eerst gevraagd of we toegang willen krijgen tot de database met behulp van een ad-hoc SQL-instructie of een nieuwe of bestaande opgeslagen procedure. Laten we ervoor kiezen om nogmaals een ad-hoc SQL-instructie te gebruiken. Vervolgens wordt gevraagd welk type SQL-query we willen gebruiken. Omdat we alle producten willen retourneren die deel uitmaken van een opgegeven categorie, willen we een SELECT-instructie schrijven die rijen retourneert.

Kies ervoor om een SELECT-instructie te maken die rijen retourneert

Afbeelding 15: Kies ervoor om een SELECT-instructie te maken die rijen retourneert (klik om de volledige afbeelding weer te geven)

De volgende stap is het definiëren van de SQL-query die wordt gebruikt voor toegang tot de gegevens. Omdat we alleen die producten willen retourneren die tot een bepaalde categorie behoren, gebruik ik dezelfde SELECT-instructie van GetProducts(), maar voeg de volgende WHERE-component toe: WHERE CategoryID = @CategoryID. De parameter @CategoryID geeft aan dat de wizard TableAdapter aangeeft dat voor de methode die we maken, een invoerparameter van het bijbehorende type is vereist (namelijk een geheel getal dat null kan worden gebruikt).

Voer een query in om alleen producten in een opgegeven categorie te retourneren

Afbeelding 16: Voer een query in om alleen producten in een opgegeven categorie te retourneren (klik om de afbeelding op volledige grootte weer te geven)

In de laatste stap kunnen we kiezen welke patronen voor gegevenstoegang moeten worden gebruikt, evenals de namen van de gegenereerde methoden aanpassen. Voor het opvulpatroon gaan we de naam wijzigen in FillByCategoryID en voor het retourneren van een DataTable-retourpatroon (de GetX-methoden ), gaan we GetProductsByCategoryID gebruiken.

Kies de namen voor de TableAdapter Methods

Afbeelding 17: Kies de namen voor de TableAdapter-methoden (klik om de volledige afbeelding weer te geven)

Nadat de wizard is voltooid, bevat de DataSet Designer de nieuwe TableAdapter-methoden.

De producten kunnen nu worden opgevraagd op categorie

Afbeelding 18: De producten kunnen nu worden opgevraagd op categorie

Neem even de tijd om een Methode GetProductByProductID(productID) toe te voegen met dezelfde techniek.

Deze geparameteriseerde query's kunnen rechtstreeks vanuit DataSet Designer worden getest. Klik met de rechtermuisknop op de methode in TableAdapter en kies Voorbeeldgegevens. Voer vervolgens de waarden in die u voor de parameters wilt gebruiken en klik op Voorbeeld.

Deze producten die tot de categorie Dranken behoren, worden weergegeven

Afbeelding 19: Deze producten die behoren tot de categorie Dranken worden weergegeven (klik om de afbeelding op volledige grootte weer te geven)

Met de methode GetProductsByCategoryID(categoryID) in onze DAL kunnen we nu een ASP.NET pagina maken waarin alleen die producten in een opgegeven categorie worden weergegeven. In het volgende voorbeeld ziet u alle producten die zich in de categorie Dranken bevinden, met een categorie-id van 1.

Dranken.asp

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Beverages.aspx.cs"
    Inherits="Beverages" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>
    <link href="Styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <h2>Beverages</h2>
        <p>
            <asp:GridView ID="GridView1" runat="server"
             CssClass="DataWebControlStyle">
               <HeaderStyle CssClass="HeaderStyle" />
               <AlternatingRowStyle CssClass="AlternatingRowStyle" />
            </asp:GridView>
             </p>
    </div>
    </form>
</body>
</html>

Beverages.aspx.cs

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using NorthwindTableAdapters;
public partial class Beverages : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        ProductsTableAdapter productsAdapter = new
         ProductsTableAdapter();
        GridView1.DataSource =
          productsAdapter.GetProductsByCategoryID(1);
        GridView1.DataBind();
    }
}

Deze producten in de categorie Dranken worden weergegeven

Afbeelding 20: Deze producten in de categorie Dranken worden weergegeven (klik om de afbeelding op volledige grootte weer te geven)

Stap 4: Gegevens invoegen, bijwerken en verwijderen

Er zijn twee patronen die vaak worden gebruikt voor het invoegen, bijwerken en verwijderen van gegevens. Het eerste patroon, dat ik het directe databasepatroon aanroep, omvat het maken van methoden die, wanneer deze worden aangeroepen, een INSERT-, UPDATE- of DELETE-opdracht uitgeven aan de database die op één databaserecord werkt. Dergelijke methoden worden meestal doorgegeven in een reeks scalaire waarden (gehele getallen, tekenreeksen, Booleaanse waarden, Datum/tijd, enzovoort) die overeenkomen met de waarden die moeten worden ingevoegd, bijgewerkt of verwijderd. Met dit patroon voor de tabel Producten zou de verwijdermethode bijvoorbeeld een geheel getalparameter bevatten, wat de Product-id van de record aangeeft die moet worden verwijderd, terwijl de invoegmethode een tekenreeks voor de ProductName, een decimaalteken voor de UnitPrice, een geheel getal voor de UnitsOnStock, enzovoort zou aannemen.

Elke aanvraag voor invoegen, bijwerken en verwijderen wordt onmiddellijk naar de database verzonden

Afbeelding 21: Elke aanvraag voor invoegen, bijwerken en verwijderen wordt onmiddellijk naar de database verzonden (klik om de volledige afbeelding weer te geven)

Het andere patroon, waarnaar ik verwijst als het batch-updatepatroon, is het bijwerken van een volledige DataSet, DataTable of het verzamelen van DataRows in één methodeaanroep. Met dit patroon verwijdert een ontwikkelaar DataRows in een DataTable, voegt deze toe en wijzigt deze, om ze vervolgens door te geven aan een updatemethode. Met deze methode worden vervolgens de Doorgegeven DataRows geïnventareerd, wordt bepaald of deze zijn gewijzigd, toegevoegd of verwijderd (via de eigenschapswaarde rowstate van DataRow) en wordt de juiste databaseaanvraag voor elke record opgegeven.

Alle wijzigingen worden gesynchroniseerd met de database wanneer de updatemethode wordt aangeroepen

Afbeelding 22: Alle wijzigingen worden gesynchroniseerd met de database wanneer de updatemethode wordt aangeroepen (klik om de volledige afbeelding weer te geven)

TableAdapter maakt standaard gebruik van het batch-updatepatroon, maar ondersteunt ook het directe DB-patroon. Omdat we bij het maken van de TableAdapter de optie 'Insert, Update en Delete-instructies genereren' hebben geselecteerd, bevat de ProductsTableAdapter een Methode Update(), waarmee het batch-updatepatroon wordt geïmplementeerd. De TableAdapter bevat een Update()-methode die de getypte DataSet, een sterk getypeerde DataTable of een of meer DataRows kan ontvangen. Als u het selectievakje GenerateDBDirectMethods hebt ingeschakeld bij het maken van de TableAdapter, wordt het directe DB-patroon ook geïmplementeerd via de methoden Insert(), Update()en Delete().

Beide gegevenswijzigingspatronen maken gebruik van de eigenschappen InsertCommand, UpdateCommand en DeleteCommand van TableAdapter om de opdrachten INSERT, UPDATE en DELETE uit te geven aan de database. U kunt de eigenschappen InsertCommand, UpdateCommand en DeleteCommand controleren en wijzigen door in de DataSet Designer op de TableAdapter te klikken en vervolgens naar het venster Eigenschappen te gaan. (Zorg ervoor dat u de TableAdapter hebt geselecteerd en dat het object ProductsTableAdapter het object is dat is geselecteerd in de vervolgkeuzelijst in het venster Eigenschappen.)

De TableAdapter heeft de eigenschappen InsertCommand, UpdateCommand en DeleteCommand

Afbeelding 23: De TableAdapter heeft InsertCommand, UpdateCommand en DeleteCommand-eigenschappen (klik om de volledige afbeelding weer te geven)

Als u een van deze eigenschappen van de databaseopdracht wilt onderzoeken of wijzigen, klikt u op de CommandText-subproperty, die de opbouwfunctie voor query's weergeeft.

De instructies INSERT, UPDATE en DELETE configureren in de opbouwfunctie voor query's

Afbeelding 24: De instructies INSERT, UPDATE en DELETE configureren in de opbouwfunctie voor query's (klik hier om de volledige afbeelding weer te geven)

In het volgende codevoorbeeld ziet u hoe u het batch-updatepatroon gebruikt om de prijs te verdubbelen van alle producten die niet worden stopgezet en die 25 eenheden op voorraad of minder hebben:

NorthwindTableAdapters.ProductsTableAdapter productsAdapter =
  new NorthwindTableAdapters.ProductsTableAdapter();
// For each product, double its price if it is not discontinued and
// there are 25 items in stock or less
Northwind.ProductsDataTable products = productsAdapter.GetProducts();
foreach (Northwind.ProductsRow product in products)
   if (!product.Discontinued && product.UnitsInStock <= 25)
      product.UnitPrice *= 2;
// Update the products
productsAdapter.Update(products);

In de onderstaande code ziet u hoe u het directe DB-patroon gebruikt om programmatisch een bepaald product te verwijderen, vervolgens een product bij te werken en vervolgens een nieuw product toe te voegen:

NorthwindTableAdapters.ProductsTableAdapter productsAdapter =
    new NorthwindTableAdapters.ProductsTableAdapter();
// Delete the product with ProductID 3
productsAdapter.Delete(3);
// Update Chai (ProductID of 1), setting the UnitsOnOrder to 15
productsAdapter.Update("Chai", 1, 1, "10 boxes x 20 bags",
  18.0m, 39, 15, 10, false, 1);
// Add a new product
productsAdapter.Insert("New Product", 1, 1,
  "12 tins per carton", 14.95m, 15, 0, 10, false);

Aangepaste methoden voor invoegen, bijwerken en verwijderen maken

De methoden Insert(), Update()en Delete() die zijn gemaakt met de directe db-methode, kunnen een beetje omslachtig zijn, met name voor tabellen met veel kolommen. Als we het vorige codevoorbeeld bekijken, is het zonder de hulp van IntelliSense niet duidelijk welke tabelkolom van de Producten aan elke invoerparameter is gekoppeld in de methoden Update() en Insert(). Het kan voorkomen dat we slechts één kolom of twee willen bijwerken of een aangepaste Insert() -methode willen die mogelijk de waarde retourneert van het nieuw ingevoegde record-ID-veld (automatisch verhogen).

Als u een dergelijke aangepaste methode wilt maken, gaat u terug naar DataSet Designer. Klik met de rechtermuisknop op de TableAdapter en kies Query toevoegen en ga terug naar de wizard TableAdapter. In het tweede scherm kunnen we aangeven welk type query moet worden gemaakt. We gaan een methode maken waarmee een nieuw product wordt toegevoegd en vervolgens de waarde van de product-id van de zojuist toegevoegde record wordt geretourneerd. Kies er daarom voor om een INSERT-query te maken.

Een methode maken om een nieuwe rij toe te voegen aan de tabel Producten

Afbeelding 25: Een methode maken om een nieuwe rij toe te voegen aan de tabel Producten (klik hier om de volledige afbeelding weer te geven)

In het volgende scherm wordt de CommandText van InsertCommand weergegeven. U kunt deze query uitbreiden door SELECT SCOPE_IDENTITY() toe te voegen aan het einde van de query, waarmee de laatste identiteitswaarde wordt geretourneerd die is ingevoegd in een identiteitskolom in hetzelfde bereik. (Zie de technische documentatie voor meer informatie over SCOPE_IDENTITY() en waarom u waarschijnlijk SCOPE_IDENTITY() wilt gebruiken in plaats van @@IDENTITY.) Zorg ervoor dat u de INSERT-instructie beëindigt met een puntkomma voordat u de SELECT-instructie toevoegt .

De query uitbreiden om de SCOPE_IDENTITY() waarde te retourneren

Afbeelding 26: De query uitbreiden om de waarde SCOPE_IDENTITY() te retourneren (klik om de afbeelding op volledige grootte weer te geven)

Geef ten slotte de nieuwe methode InsertProduct een naam.

De naam van de nieuwe methode instellen op InsertProduct

Afbeelding 27: Stel de naam van de nieuwe methode in op InsertProduct (klik om de afbeelding op volledige grootte weer te geven)

Wanneer u terugkeert naar de DataSet Designer, ziet u dat de ProductsTableAdapter een nieuwe methode bevat, InsertProduct. Als deze nieuwe methode geen parameter heeft voor elke kolom in de tabel Producten , bent u waarschijnlijk vergeten de INSERT-instructie met een puntkomma te beëindigen. Configureer de InsertProduct-methode en zorg ervoor dat u een puntkomma als scheidingsteken tussen de INSERT en SELECT-instructies gebruikt.

Standaard geven invoegmethoden geen querymethoden op, wat betekent dat ze het aantal betrokken rijen retourneren. We willen echter dat de InsertProduct-methode de waarde retourneert die door de query wordt geretourneerd, niet het aantal rijen dat wordt beïnvloed. Hiervoor past u de eigenschap ExecuteMode van de methode InsertProduct aan op Scalar.

De eigenschap ExecuteMode wijzigen in Scalar

Afbeelding 28: wijzig de eigenschap ExecuteMode in Scalar (klik om de afbeelding op volledige grootte weer te geven)

De volgende code toont deze nieuwe InsertProduct-methode in actie:

NorthwindTableAdapters.ProductsTableAdapter productsAdapter =
    new NorthwindTableAdapters.ProductsTableAdapter();
// Add a new product
int new_productID = Convert.ToInt32(productsAdapter.InsertProduct
    ("New Product", 1, 1, "12 tins per carton", 14.95m, 10, 0, 10, false));
// On second thought, delete the product
productsAdapter.Delete(new_productID);

Stap 5: de Gegevenstoegangslaag voltooien

Houd er rekening mee dat de klasse ProductsTableAdapters de waarden CategoryID en SupplierID uit de tabel Producten retourneert, maar niet de kolom CategoryName uit de tabel Categorieën of de kolom CompanyName uit de tabel Leveranciers bevat, hoewel dit waarschijnlijk de kolommen zijn die we willen weergeven wanneer productgegevens worden weergegeven. We kunnen de initiële methode van TableAdapter, GetProducts(), uitbreiden om zowel de kolomwaarden CategoryName als CompanyName op te nemen, waarmee ook de sterk getypte gegevenstabel wordt bijgewerkt om deze nieuwe kolommen op te nemen.

Dit kan echter een probleem opleveren, omdat de methoden van TableAdapter voor het invoegen, bijwerken en verwijderen van gegevens zijn gebaseerd op deze initiële methode. Gelukkig worden de automatisch gegenereerde methoden voor het invoegen, bijwerken en verwijderen niet beïnvloed door subquery's in de SELECT-component . Door ervoor te zorgen dat we onze query's als subquery's toevoegen aan categorieën en leveranciers , in plaats van JOIN's , hoeven we deze methoden niet opnieuw te bewerken voor het wijzigen van gegevens. Klik met de rechtermuisknop op de methode GetProducts() in de ProductsTableAdapter en kies Configureren. Pas vervolgens de SELECT-component aan zodat deze er als volgt uitziet:

SELECT     ProductID, ProductName, SupplierID, CategoryID,
QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued,
(SELECT CategoryName FROM Categories
WHERE Categories.CategoryID = Products.CategoryID) as CategoryName,
(SELECT CompanyName FROM Suppliers
WHERE Suppliers.SupplierID = Products.SupplierID) as SupplierName
FROM         Products

De SELECT-instructie voor de methode GetProducts() bijwerken

Afbeelding 29: de SELECT-instructie voor de Methode GetProducts() bijwerken (klik om de afbeelding op volledige grootte weer te geven)

Na het bijwerken van de methode GetProducts() voor het gebruik van deze nieuwe query bevat de DataTable twee nieuwe kolommen: CategoryName en SupplierName.

De gegevenstabel Producten bevat twee nieuwe kolommen

Afbeelding 30: De gegevenstabel Producten heeft twee nieuwe kolommen

Neem even de tijd om de SELECT-component bij te werken in de methode GetProductsByCategoryID(categoryID).

Als u getProducts()SELECT bijwerkt met behulp van join-syntaxis , kan de DataSet Designer de methoden voor het invoegen, bijwerken en verwijderen van databasegegevens niet automatisch genereren met behulp van het directe DB-patroon. In plaats daarvan moet u ze handmatig maken zoals we eerder in deze zelfstudie hebben gedaan met de methode InsertProduct . Bovendien moet u handmatig de eigenschapswaarden InsertCommand, UpdateCommand en DeleteCommand opgeven als u het patroon voor het bijwerken van batches wilt gebruiken.

De resterende TableAdapters toevoegen

Tot nu toe hebben we alleen gekeken naar het werken met één TableAdapter voor één databasetabel. De Northwind-database bevat echter verschillende gerelateerde tabellen waarmee we moeten werken in onze webtoepassing. Een getypte gegevensset kan meerdere gerelateerde gegevenstabellen bevatten. Daarom moeten we DataTables toevoegen voor de andere tabellen die we in deze handleidingen gaan gebruiken om onze DAL te voltooien. Als u een nieuwe TableAdapter wilt toevoegen aan een getypte gegevensset, opent u DataSet Designer, klikt u met de rechtermuisknop in de ontwerpfunctie en kiest u Toevoegen/TableAdapter. Hiermee maakt u een nieuwe DataTable en TableAdapter en doorloopt u de wizard die we eerder in deze tutorial hebben onderzocht.

Het maken van de volgende TableAdapters en methoden duurt enkele minuten met behulp van de volgende query's. Houd er rekening mee dat de query's in de ProductsTableAdapter de subquery's bevatten om de categorie- en leveranciersnamen van elk product op te halen. Als u de volgende stappen hebt uitgevoerd, hebt u bovendien de methoden GetProducts() en GetProductsByCategoryID(categoryID) van de klasse ProductsTableAdapter al toegevoegd.

  • ProductenTableAdapter

    • Producten:

      SELECT     ProductID, ProductName, SupplierID, 
      CategoryID, QuantityPerUnit, UnitPrice, UnitsInStock, 
      UnitsOnOrder, ReorderLevel, Discontinued, 
      (SELECT CategoryName FROM Categories WHERE
      Categories.CategoryID = Products.CategoryID) as 
      CategoryName, (SELECT CompanyName FROM Suppliers
      WHERE Suppliers.SupplierID = Products.SupplierID) 
      as SupplierName
      FROM         Products
      
    • GetProductsByCategoryID:

      SELECT     ProductID, ProductName, SupplierID, CategoryID,
      QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder,
      ReorderLevel, Discontinued, (SELECT CategoryName
      FROM Categories WHERE Categories.CategoryID = 
      Products.CategoryID) as CategoryName,
      (SELECT CompanyName FROM Suppliers WHERE
      Suppliers.SupplierID = Products.SupplierID)
      as SupplierName
      FROM         Products
      WHERE      CategoryID = @CategoryID
      
    • GetProductsBySupplierID:

      SELECT     ProductID, ProductName, SupplierID, CategoryID,
      QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder,
      ReorderLevel, Discontinued, (SELECT CategoryName
      FROM Categories WHERE Categories.CategoryID = 
      Products.CategoryID) as CategoryName, 
      (SELECT CompanyName FROM Suppliers WHERE 
      Suppliers.SupplierID = Products.SupplierID) as SupplierName
      FROM         Products
      WHERE SupplierID = @SupplierID
      
    • GetProductByProductID:

      SELECT     ProductID, ProductName, SupplierID, CategoryID,
      QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder,
      ReorderLevel, Discontinued, (SELECT CategoryName 
      FROM Categories WHERE Categories.CategoryID = 
      Products.CategoryID) as CategoryName, 
      (SELECT CompanyName FROM Suppliers WHERE Suppliers.SupplierID = Products.SupplierID) 
      as SupplierName
      FROM         Products
      WHERE ProductID = @ProductID
      
  • CategorieënTafelAdapter

    • Categorieën:

      SELECT     CategoryID, CategoryName, Description
      FROM         Categories
      
    • GetCategoryByCategoryID:

      SELECT     CategoryID, CategoryName, Description
      FROM         Categories
      WHERE CategoryID = @CategoryID
      
  • LeveranciersTafelAdapter

    • Leveranciers:

      SELECT     SupplierID, CompanyName, Address,
      City, Country, Phone
      FROM         Suppliers
      
    • Leveranciers per land krijgen:

      SELECT     SupplierID, CompanyName, Address,
      City, Country, Phone
      FROM         Suppliers
      WHERE Country = @Country
      
    • GetSupplierBySupplierID:

      SELECT     SupplierID, CompanyName, Address,
      City, Country, Phone
      FROM         Suppliers
      WHERE SupplierID = @SupplierID
      
  • Medewerkers TableAdapter

    • Get-medewerkers:

      SELECT     EmployeeID, LastName, FirstName, Title,
      HireDate, ReportsTo, Country
      FROM         Employees
      
    • GetEmployeesByManager:

      SELECT     EmployeeID, LastName, FirstName, Title, 
      HireDate, ReportsTo, Country
      FROM         Employees
      WHERE ReportsTo = @ManagerID
      
    • GetEmployeeByEmployeeID:

      SELECT     EmployeeID, LastName, FirstName, Title,
      HireDate, ReportsTo, Country
      FROM         Employees
      WHERE EmployeeID = @EmployeeID
      

De DataSet Designer nadat de vier TableAdapters zijn toegevoegd

Afbeelding 31: De ontwerpfunctie voor gegevenssets nadat de vier TableAdapters zijn toegevoegd (klik om de afbeelding op volledige grootte weer te geven)

Aangepaste code toevoegen aan de DAL

De TableAdapters en DataTables die zijn toegevoegd aan de getypte gegevensset, worden uitgedrukt als een XML-schemadefinitiebestand (Northwind.xsd). U kunt deze schemagegevens weergeven door met de rechtermuisknop op het bestand Northwind.xsd in Solution Explorer te klikken en Code weergeven te kiezen.

Het XSD-bestand (XML-schemadefinitie) voor de gegevensset met het type Northwinds

Afbeelding 32: Het XSD-bestand (XML-schemadefinitie) voor de gegevensset met het type Northwinds (klik hier om de volledige afbeelding weer te geven)

Deze schema-informatie wordt tijdens het ontwerpen vertaald in C# of Visual Basic-code wanneer deze is gecompileerd of tijdens runtime (indien nodig), waarna u deze kunt doorlopen met het foutopsporingsprogramma. Als u deze automatisch gegenereerde code wilt weergeven, gaat u naar de klasseweergave en zoomt u in op de TableAdapter- of Getypte DataSet-klassen. Als u de klasweergave niet op het scherm ziet, gaat u naar het menu Beeld en selecteert u deze daar of drukt u op Ctrl+Shift+C. In de klasseweergave ziet u de eigenschappen, methoden en gebeurtenissen van de klassen Getypte DataSet en TableAdapter. Als u de code voor een bepaalde methode wilt weergeven, dubbelklikt u op de naam van de methode in de klasseweergave of klikt u erop met de rechtermuisknop en kiest u Ga naar definitie.

Inspecteer de automatisch gegenereerde code door Ga naar definitie te selecteren in de klasseweergave

Afbeelding 33: De automatisch gegenereerde code controleren door Go To Definition te selecteren in de klasseweergave

Hoewel automatisch gegenereerde code een geweldige tijdbesparing kan zijn, is de code vaak zeer algemeen en moet deze worden aangepast om te voldoen aan de unieke behoeften van een toepassing. Het risico van het uitbreiden van automatisch gegenereerde code is echter dat het hulpprogramma dat de code heeft gegenereerd, kan besluiten dat het tijd is om uw aanpassingen opnieuw te genereren en over te schrijven. Met het nieuwe concept van .NET 2.0 voor gedeeltelijke klassen kunt u eenvoudig een klasse splitsen over meerdere bestanden. Hierdoor kunnen we onze eigen methoden, eigenschappen en gebeurtenissen toevoegen aan de automatisch gegenereerde klassen zonder dat u zich zorgen hoeft te maken over het overschrijven van onze aanpassingen door Visual Studio.

Laten we een GetProducts() -methode toevoegen aan de klasse SuppliersRow om te laten zien hoe u de DAL kunt aanpassen. De klasse SuppliersRow vertegenwoordigt één record in de tabel Leveranciers ; elke leverancier kan nul tot veel producten leveren, dus GetProducts() retourneert die producten van de opgegeven leverancier. Als u dit wilt doen, maakt u een nieuw klassebestand in de map App_Code met de naam SuppliersRow.cs en voegt u de volgende code toe:

using System;
using System.Data;
using NorthwindTableAdapters;
public partial class Northwind
{
    public partial class SuppliersRow
    {
        public Northwind.ProductsDataTable GetProducts()
        {
            ProductsTableAdapter productsAdapter =
             new ProductsTableAdapter();
            return
              productsAdapter.GetProductsBySupplierID(this.SupplierID);
        }
    }
}

Met deze gedeeltelijke klasse wordt de compiler geïnstrueerd dat bij het bouwen van de klasse Northwind.SuppliersRow de GetProducts() -methode die we zojuist hebben gedefinieerd, moet worden opgenomen. Als u uw project bouwt en vervolgens terugkeert naar de klasseweergave, ziet u dat GetProducts() nu wordt vermeld als een methode van Northwind.SuppliersRow.

De methode GetProducts() maakt nu deel uit van de klasse Northwind.SuppliersRow

Afbeelding 34: De methode GetProducts() maakt nu deel uit van de klasse Northwind.SuppliersRow

De methode GetProducts() kan nu worden gebruikt om de set producten voor een bepaalde leverancier op te sommen, zoals in de volgende code wordt weergegeven:

NorthwindTableAdapters.SuppliersTableAdapter suppliersAdapter =
    new NorthwindTableAdapters.SuppliersTableAdapter();
// Get all of the suppliers
Northwind.SuppliersDataTable suppliers =
  suppliersAdapter.GetSuppliers();
// Enumerate the suppliers
foreach (Northwind.SuppliersRow supplier in suppliers)
{
    Response.Write("Supplier: " + supplier.CompanyName);
    Response.Write("<ul>");
    // List the products for this supplier
    Northwind.ProductsDataTable products = supplier.GetProducts();
    foreach (Northwind.ProductsRow product in products)
        Response.Write("<li>" + product.ProductName + "</li>");
    Response.Write("</ul><p> </p>");
}

Deze gegevens kunnen ook worden weergegeven in elk van de data-webcontrols van ASP.NET. Op de volgende pagina wordt een GridView-besturingselement met twee velden gebruikt:

  • Een BoundField met de naam van elke leverancier en
  • Een TemplateField dat een BulletedList-besturingselement bevat dat is gekoppeld aan de resultaten die door de GetProducts()-methode voor elke leverancier worden geretourneerd.

In toekomstige tutorials wordt uitgelegd hoe u dergelijke hoofddetailrapporten kunt weergeven. Dit voorbeeld is nu ontworpen om te illustreren met behulp van de aangepaste methode die is toegevoegd aan de klasse Northwind.SuppliersRow .

SuppliersAndProducts.aspx

<%@ Page Language="C#" CodeFile="SuppliersAndProducts.aspx.cs"
    AutoEventWireup="true" Inherits="SuppliersAndProducts" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>
    <link href="Styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <h2>
            Suppliers and Their Products</h2>
        <p>
            <asp:GridView ID="GridView1" runat="server"
             AutoGenerateColumns="False"
             CssClass="DataWebControlStyle">
                <HeaderStyle CssClass="HeaderStyle" />
                <AlternatingRowStyle CssClass="AlternatingRowStyle" />
                <Columns>
                    <asp:BoundField DataField="CompanyName"
                      HeaderText="Supplier" />
                    <asp:TemplateField HeaderText="Products">
                        <ItemTemplate>
                            <asp:BulletedList ID="BulletedList1"
                             runat="server" DataSource="<%# ((Northwind.SuppliersRow) ((System.Data.DataRowView) Container.DataItem).Row).GetProducts() %>"
                                 DataTextField="ProductName">
                            </asp:BulletedList>
                        </ItemTemplate>
                    </asp:TemplateField>
                </Columns>
            </asp:GridView>
             </p>
    </div>
    </form>
</body>
</html>

SuppliersAndProducts.aspx.cs

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using NorthwindTableAdapters;
public partial class SuppliersAndProducts : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        SuppliersTableAdapter suppliersAdapter = new
          SuppliersTableAdapter();
        GridView1.DataSource = suppliersAdapter.GetSuppliers();
        GridView1.DataBind();
    }
}

De bedrijfsnaam van de leverancier wordt vermeld in de linkerkolom, de producten in de rechterkolom

Afbeelding 35: De bedrijfsnaam van de leverancier wordt weergegeven in de linkerkolom, de producten in de rechterkolom (klik om de volledige afbeelding weer te geven)

Samenvatting

Wanneer u een webtoepassing bouwt, zou het maken van de DAL een van uw eerste stappen moeten zijn, nog voordat u begint met het maken van de presentatielaag. Met Visual Studio is het maken van een DAL op basis van getypte gegevenssets een taak die in 10-15 minuten kan worden uitgevoerd zonder een regel code te schrijven. De toekomstige tutorials zullen voortbouwen op deze DAL. In de volgende zelfstudie definiëren we een aantal bedrijfsregels en zien we hoe u deze implementeert in een afzonderlijke bedrijfslogicalaag.

Veel plezier met programmeren!

Meer lezen

Raadpleeg de volgende bronnen voor meer informatie over de onderwerpen die in deze zelfstudie worden besproken:

Videotraining over onderwerpen in deze tutorial

Over de auteur

Scott Mitchell, auteur van zeven ASP/ASP.NET-boeken en oprichter van 4GuysFromRolla.com, werkt sinds 1998 met Microsoft-webtechnologieën. Scott werkt als onafhankelijk consultant, trainer en schrijver. Zijn laatste boek is Sams Teach Yourself ASP.NET 2.0 in 24 uur. Hij kan worden bereikt op mitchell@4GuysFromRolla.com.

Speciale dank aan

Deze tutorialreeks is beoordeeld door veel behulpzame beoordelers. Hoofdrevisoren voor deze zelfstudie waren Ron Green, Hilton Giesenow, Dennis Patterson, Liz Shulok, Abel Gomez en Carlos Santos. Bent u geïnteresseerd in het bekijken van mijn aanstaande MSDN-artikelen? Zo ja, laat iets van je horen via mitchell@4GuysFromRolla.com.