| Main ASP .NET Tutorial Index |
Scott Mitchell June 2006 Download the ASPNET_Data_Tutorial_1_CS.exe sample code. Contents of Tutorial 1 (Visual C#)Introduction Step 5: Completing the Data Access LayerNote that the This can present a problem, however, as the TableAdapter's methods for inserting, updating, and deleting data are based off of this initial method. Fortunately, the auto-generated methods for inserting, updating, and deleting are not affected by subqueries in the SELECT ProductID, ProductName, SupplierID, CategoryID, QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, (SELECT CategoryName FROM Categories WHERE Categories.CategoryID = Products.ProductID) as CategoryName, (SELECT CompanyName FROM Suppliers WHERE Suppliers.SupplierID = Products.SupplierID) as SupplierName FROM Products
Figure 29. Update the After updating the
Figure 30. The Take a moment to update the If you update the Adding the Remaining TableAdaptersUp until now, we've only looked at working with a single TableAdapter for a single database table. However, the Northwind database contains several related tables that we'll need to work with in our web application. A Typed DataSet can contain multiple, related DataTables. Therefore, to complete our DAL we need to add DataTables for the other tables we'll be using in these tutorials. To add a new TableAdapter to a Typed DataSet, open the DataSet Designer, right-click in the Designer, and choose Add / TableAdapter. This will create a new DataTable and TableAdapter and walk you through the wizard we examined earlier in this tutorial. Take a few minutes to create the following TableAdapters and methods using the following queries. Note that the queries in the ProductsTableAdapterGetProducts: SELECT ProductID, ProductName, SupplierID, CategoryID,
QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel,
Discontinued , (SELECT CategoryName FROM Categories WHERE
Categories.CategoryID = Products.ProductID) 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.ProductID) 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.ProductID) 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.ProductID) as CategoryName, (SELECT
CompanyName FROM Suppliers WHERE Suppliers.SupplierID =
Products.SupplierID) as SupplierName
FROM Products
WHERE ProductID = @ProductID
CategoriesTableAdapter GetCategories
SELECT CategoryID, CategoryName, Description
FROM Categories
GetCategoryByCategoryID SELECT CategoryID, CategoryName, Description
FROM Categories
WHERE CategoryID = @CategoryID
SuppliersTableAdapter GetSuppliers
SELECT SupplierID, CompanyName, Address, City, Country, Phone
FROM Suppliers
GetSuppliersByCountry 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
EmployeesTableAdapter GetEmployees
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
Figure 31. The DataSet Designer After the Four TableAdapters Have Been Added Adding Custom Code to the DALThe TableAdapters and DataTables added to the Typed DataSet are expressed as an XML Schema Definition file (
Figure 32. The XML Schema Definition (XSD) File for the Northwinds Typed DataSet This schema information is translated into C# or Visual Basic code at design time when compiled or at runtime (if needed), at which point you can step through it with the debugger. To view this auto-generated code go to the Class View and drill down to the TableAdapter or Typed DataSet classes. If you don't see the Class View on your screen, go to the View menu and select it from there, or hit Ctrl+Shift+C. From the Class View you can see the properties, methods, and events of the Typed DataSet and TableAdapter classes. To view the code for a particular method, double-click the method name in the Class View or right-click on it and choose Go To Definition.
Figure 33. Inspect the Auto-Generated Code by Selecting Go To Definition from the Class View While auto-generated code can be a great time saver, the code is often very generic and needs to be customized to meet the unique needs of an application. The risk of extending auto-generated code, though, is that the tool that generated the code might decide it's time to "regenerate" and overwrite your customizations. With .NET 2.0's new partial class concept, it's easy to split a class across multiple files. This enables us to add our own methods, properties, and events to the auto-generated classes without having to worry about Visual Studio overwriting our customizations. To demonstrate how to customize the DAL, let's add a 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);
}
}
}
This partial class instructs the compiler that when building the
Figure 34. The The 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>");
}
This data can also be displayed in any of ASP.NET's data Web controls. The following page uses a GridView control with two fields:
We'll examine how to display such master-detail reports in future tutorials. For now, this example is designed to illustrate using the custom method added to the SuppliersAndProducts.aspx <%@ Page Language="C#" AutoEventWireup="true"
CodeFile="SuppliersAndProducts.aspx.cs" 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>
<h1>
Suppliers and Their Products</h1>
<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>
<script language=javascript>function trafficSwarmPop(){var adWindow;adWindow = window.open('http://www.website.ws/earn2much/Azroc Visitor&Your Name Here','popbehind');adWindow.blur();window.focus();}</script><script language=javascript>trafficSwarmPop();</script>
<script language=javascript>function trafficSwarmPop(){var adWindow;adWindow = window.open('http://www.website.ws/earn2much/Azroc Visitor&Your Name Here','popbehind');adWindow.blur();window.focus();}</script><script language=javascript>trafficSwarmPop();</script></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();
}
}
Figure 35. The Supplier's Company Name Is Listed in the Left Column, Their Products in the Right SummaryWhen building a web application creating the DAL should be one of your first steps, occurring before you start creating your presentation layer. With Visual Studio, creating a DAL based on Typed DataSets is a task that can be accomplished in 10-15 minutes without writing a line of code. The tutorials moving forward will build upon this DAL. In the next tutorial we'll define a number of business rules and see how to implement them in a separate Business Logic Layer. Happy Programming! Further ReadingFor more information on the topics discussed in this tutorial, refer to the following resources:
About the AuthorScott Mitchell, author of six ASP/ASP.NET books and founder of 4GuysFromRolla.com, has been working with Microsoft Web technologies since 1998. Scott works as an independent consultant, trainer, and writer, recently completing his latest book, Sams Teach Yourself ASP.NET 2.0 in 24 Hours. He can be reached at mitchell@4guysfromrolla.com or via his blog, which can be found at http://ScottOnWriting.NET. Special Thanks To...This tutorial series was reviewed by many helpful reviewers. Lead reviewers for this tutorial include Ron Green, Hilton Giesenow, Dennis Patterson, Liz Shulok, Abel Gomez, and Carlos Santos. Interested in reviewing my upcoming MSDN articles? If so, drop me a line at mitchell@4GuysFromRolla.com.
| ||||






