Assignment 5 -- Working with SQL Server Express and Data Listing Controls
DataAccess Class: This week's exercises
all work with database data. We will use a custom class named DataAccess that allows us to remove all the messy details of data access (connection objects, DataAdapers and Command objects) from our code and push them down into a class. The first step in this
exercise is to add the DataAcess class to your application. Steps:
Use VWD to create a new class. Right click on the
application root folder (c:\...) and select "Add new item..."
Click "class" and name it DataAccess.cs.
Cut & paste the code from DataAccess.cs.txt into this file and save the file. The dataAccess class is now accessible from throughout your application just as if it were part of the .NET class library.
web.config: The new DataAccess class looks in the web.config file for
a database connection string. The web.config file may be in the same folder as
your .aspx page or in any of its parent folders up to the root folder. The root folder is
a convenient place to place the web.config file because connection strings defined at the top level are accessible from all the child folders. Copy the
connection information from web.config.txt
(view source) and put it into your web.config file. Note: The web.config
files generated by Visual Web Developer 2008 will not work with .NET 2.0
(the version on Yorktown). I suggest using the simpler web.config text
used in the link above.
Exercises:
-
GridView.aspx - In this exercise you will
create a small database, use the DataAccess class to populate a
dataTable and bind the dataTable to a GridView control. Steps:
- Create & populate database
- Create a new database by right clicking the root folder in
VWD. Select "SQL Database" and name it "A05Customers"
- Open
the database and add a new table "tblCustomers" by right
clicking on the "Tables" folder and selecting "Add New Table."
Add three fields with the following attributes:
| Column Name |
Data Type |
Allow Nulls |
| CustID* |
int |
no |
| NameF |
varchar(50) |
yes |
| NameL |
varchar(50) |
no |
*CustID is the primary key and an auto-number field. To define
it as primary key right click on the field and select "primary
key." In the
column properties for CustID select "Is Identity" "yes." - Save
the table as "tblCustomers" and close the table designer.
- Add some data to the table. In Server Explorer click on
Tables to see your new table. Right-click on tblCustomer and
select "Show Table Data."
- Add at least three rows of data.
- The database is now
ready to be used.
- Web.Config
- Create a connection string named "A05CustomerData" in your
web.config file pointing to your new database. (see instructions
above).
- Populating a GridView Control
- Create a new web form named "GridView.aspx"
- Drag a
GridView control from the tool box. Change its ID to "gvCustomers"
-
Populate the GridView from the database with the following code:
- void page_load()
{
//Initialize dataAccess class
DataAccess myDA = new DataAccess("A05CustomerData");
//Populate dataTable and bind to GridView Control
string strSQL = "Select * from tblCustomers";
gvCustomers.DataSource = myDA.FillDataTable(strSQL);
gvCustomers.DataBind();
}
- Formatting
- Add some formatting to make it pretty.
- Uploading to Yorktown
- All App_ folders must be located in the root
directory of your Aspen account. This is the directory that you
start in when you log in to Aspen. Create the folders App_Data
for your database and App_Code for your C# class code.
You can test that your root folder on Yorktown is configured as
an Application by running the following code in a page_load
subroutine. The .aspx page can be in any folder of your account.
Response.Write("Application root: " +
Request.ApplicationPath.ToString());
This code should output something line: "Application root:
/Smithj88" where Smithj88 is your Aspen root directory. If it
doesn't please contact Professor Sandvig.
- When using Aspen to upload database files (.mdf) to the
server you may get the error "File is locked or deleted."
Any of the following will usually fix this problem:
- Detach the database in Visual Studio right clicking on
the database and selecting "detach."
- Close Visual Studio
so Windows unlocks the file.
- Delete the .LDF transaction
log file that has the same name as the database.
-
UserControl/default.aspx - This exercise is based on
the User Control exercise in assignment 4. Copy UserControl.aspx, SearchBrowse.aspx and SearchMenu.ascx from A04 into your A05 folder. Test them to make sure they still work.
In this exercise you will replace the static music styles menu used in A04 with
a dynamic menu queried from the music store database. Steps:
- Replace the static links in SearchMenu.ascx with a DataList control.
- The DataList requires an ItemTemplate to define the layout. The sample uses regular HTML anchor tags. The syntax is:
<ItemTemplate>
<a class="menulink" href="SearchBrowse.aspx?style=<%# Eval("intStyleID") %>">
<%# Eval("strStyleName") %>
</a>
<br />
</ItemTemplate>
-
Add the MusicStore database to your application as follows:
- Download
MusicStoreSample.zip, unzip it and place the .mdf file in the App_Data folder
located in the applications root folder.
- View the database in VWD by double clicking on the database icon. This will change the view from "Solution Explorer" to "Server Explorer." Viewing the database should display its tables, etc. Right clicking on the database folder displays options for creating queries, viewing properties, viewing table data, etc.
- web.config - add a new connection string to
you web.config file pointing to the MusicStore database.
- Populating the DataList: Populate the
datalist using code similar to the code shown in Exercise 1.
- SQL: VWD includes a query builder that will write SQL select statements.
- Right click on the Tables folder and select "New Query" Create a query that retrieves all the style names & style IDs and sorts by name.
- tblStyles includes styles for which the database has no items. List only styles that have associated ASINs by joining tblStyles and tblStyleASIN.
- Use the "distinct" keyword in the SQL statement to eliminate duplicates. Test the query in VWD by clicking the
! icon.
- Paste the SQL statement into your .ascx page and it should
work perfectly.
- SearchBrowse.aspx - This page retrieves the search or browse query from the querystring and displays search results in a
DataList. The query is concatenated into the appropriate SQL statement (search or browse), the DataAccess class is used to retrieve the data, and
the data is bound to a DataList control.
Instructions for retrieving the data programmatically and binding to a DataList:
- The DataList control is a good control for displaying
the items retrieved from the database.
The DataList used in the style menu from the previous
exercise would be a good template.
- Retrieve the parameters search & browse from the querystring and assign
them to local variables.
- Request.QueryString["..."] returns a null if the parameter is not found. Check if strSearch retrieved a string using the syntax: if (strSearch != null) ...
- The sql statement for a search is:
strSQL = "SELECT distinct tblStyleASIN.strASIN, tblDescription.strTitle, tblDescription.strArtist, tblDescription.dblPrice, tblDescription.strReview, dbo.tblDescription.strImageDir " +
"FROM tblStyleASIN INNER JOIN tblDescription ON tblStyleASIN.strASIN = tblDescription.strASIN " +
" WHERE (tblDescription.strArtist LIKE '%" + strSearch + "%') or (tblDescription.strTitle LIKE '%" + strSearch + "%') or (tblDescription.strReview LIKE '%" + strSearch + "%') " +
" ORDER BY tblDescription.strTitle" ;
- The SQL for browse retrieves the same fields but the "WHERE " checks only in tblStyleASIN for matching StyleIDs.
- It is good practice to list the number of items found in
a search. The dataAccess class has a count property for the
number of records retrieved. Display a count of the number
of items retrieved by the query.
- Use the DataAccess class to retrieve the data and bind it to the
DataList.
- DataList ItemTemplate:
- Images: The URL for all the images is:
http://yorktown.cbe.wwu.edu/sandvig/MusicStore/MusicImages/AAAAA.01.MZZZZZZZ.jpg
where "AAAAA" is the ASIN.
- The price should be formatted as currency. This can
be done using either of the following syntax options:
<%# Eval("dblPrice","{0:c}") %>
<%# String.Format("{0:c}", Eval("dblPrice"))%>
-
ListCustomers.aspx and EditCustomers.aspx - The editing features of the DataList and GridView have a good "wow" factor but not useful in most situations. This exercise removes the insert & edit features from the datalist and puts them into a separate page for adding and editing customer information.
Steps:
- Use VWD to create a new SQL Server database named "CustomerData" in your App_Data folder. Add a table named tblCustomers and the fields CustID (identify field & primary key), NameF and NameL. Add a couple of records of data to the database for testing.
- Add a new connection string to your web config file that points to the "CustomerData" database.
- ListCustomers.aspx:
- Use DataListEdit.aspx (source) as a template for both ListCustomers.aspx and EditCustomers.aspx.
Before you modify ListCustomers.aspx it would be a good
idea to get it working to make sure your database connection
is OK.
- Remove unneeded editing subroutines
(Insert, Update, Edit) from ListCustomers.aspx. In the DataList's ItemTemplate change the editing LinkButton to a Hyperlink control. Replace the "commandName" property with:
NavigateUrl=' <%# "EditCustomers.aspx?CustID=" & Eval("CustID") %>'
- Add a new link "Add New Customer" above the
DataList that points to EditCustomers.aspx. Test & debug the page.
- EditCustomers.aspx:
- This page handles four
scenarios:
- New customer: page
initially loading
- New customer: button
click
- Edit customer: page
initially loading
- Edit customer: button
click
- When the page loads it checks the querystring for a CustID.
This determines if it is editing an exisitng customer or
adding a new one. If a customer ID is found in the
querystring it looks up the customer's data and
populates the textboxes. Create a variable named strCustID.
This variable needs to have page level scope
(initialized outside any methods) so that it can be
accessed from the button click handler.
- When the page loads it checks to see if the querystring contains a CustID. Do
this in the Page_Load() method with:
if (Request.QueryString["CustID"] != null) strCustID =
Request.QueryString["CustID"];
- The next step is to
create a method that populates the textboxes with
data from the database. Copy the "FillDataList(...)"
method from DataListEdit.aspx and rename it "FillTextBoxes()."
Remove the method's parameters list since we are not
passing any parameters.
- Use the DataAccess class to retrieve the customer data and
populate a dataTable. The syntax to copy the data from the dataTable to a textbox is:
tbNameF.Text = Convert.ToString(dt.Rows[0]["NameF"]);
- The button should read "Add" or "Edit" depending upon the presence of a CustID.
- The handler for the button_click event
uses an if statement to determine which SQL statement to use (Insert or Update). Syntax:
if (strCustID == null) ...
- It then uses the ExecuteNonQuery method of DataAccess to execute
the SQL statement.
- After the SQL statement is executed redirect back to ListCustomers.aspx (Tip: error messages may be lost when the page redirects.
Add the redirect after debugging the code).