Creating the Home Page for a Simple Storefront with LINQ

In the last article, we laid out the plans for a simple storefront for the Adventure Works Cycles sample database. We briefly examined the database structure, and created a master page to unify the look of our new web site. We also created a page that would display the appropriate image given a ProductID through the query string. In this article, we'll continue with the construction of the storefront.

Contributed by
Rating: 5 stars5 stars5 stars5 stars5 stars / 8
May 06, 2008
Rate this Article:
MEH MEH++


SEARCH ASP FREE
TOOLS YOU CAN USE

advertisement

Creating the Home Page

Let's create the store's home page. On this page will be a short welcome messages, a link to the product browse page, and then a short list of the latest products. We'll tackle the basic structure of the page first, and then we can move on to the meat of the page: using LINQ with ASP.NET. Create a Default.aspx page. Be sure to set its master page to MasterPage.master, which we created in the last article. The page will be created with a simple Content control. Here's the page without the latest items part:

<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" 
AutoEventWireup="true" CodeFile="Default.aspx.cs" 
Inherits="_Default" Title="Adventure Works Cycles" %>


<asp:Content ID="Content1" ContentPlaceHolderID="content" 
Runat="Server">

<p>Welcome to Adventure Works Cycles, your source for cycles and cycling accessories.</p>

<p><a href="Browse.aspx">Browse Products</a></p>

<p>Check out some of our latest items:</p>


</asp:Content>


Now we need a control that will display the latest items for us. Let's go with a ListView control, which is relatively new and easy to work with:


<asp:ListView ID="LatestItemsView" runat="server">

</asp:ListView>


Before the ListView becomes operational, we need to provide it with a few templates. First is the LayoutTemplate, which defines the “master layout,” if you will, of the ListView. Place this inside of the ListView tags:


<LayoutTemplate>

 <p>Here are some of our latest items:</p>

 <asp:PlaceHolder ID="itemPlaceholder" runat="server" />

 </LayoutTemplate>


Notice how we provide a PlaceHolder control here. It's a placeholder for the list of items, and it's a necessary part of LayoutTemplate. It also must have the name “itemPlaceholder” in order to work.

ItemTemplate


Next comes the ItemTemplate, which is the template for an individual item in the ListView. Place this alongside the LayoutTemplate:


<ItemTemplate>

 <div>

 <img src="ProductPicture.aspx?id=<%#Eval("ProductID") %>" alt="Product Picture" />

 <br />

 <strong><a href="Product.aspx?id=<%#Eval("ProductID") %>">

 <%#Eval("Name") %>

 </a></strong>

 </div>

</ItemTemplate>


The above displays a picture of the product, the name of the product, and a link to view the product (though, of course, the view functionality is not done). We access the various fields of the entry using Eval, passing in the appropriate field's name. When the page is viewed, the code tags are, of course, replaced with the appropriate values.

It doesn't take much to see that the above markup will generate a very primitive list of items, but we'll worry about replacing the layout in a moment. Right now we need to wire up our ListView. There are two ways we can databind our control using LINQ and ASP.NET. The first way is to databind it directly through code, and the second way is to use LinqDataSource. Here, we're going to use the first method and manually databind it in Page_Load. We'll discuss the second method in a bit.

To databind the control, we simply need to query the database using LINQ as we would in a normal application, and then we need to assign the result to the ListView control's DataSource attribute. Finally, we need to call the DataBind method. Here's how it's done:

protected void Page_Load(object sender, EventArgs e)

{

 AdventureWorksDataContext db = new AdventureWorksDataContext();

 var latestItems = (from p in db.Products

 orderby p.SellStartDate descending

 select p).Take(3);

LatestItemsView.DataSource = latestItems;

LatestItemsView.DataBind();

}


The only thing strange in the code, perhaps, is Take. Take simply limits the amount of items returned. Here, we get the first three results. Besides Take, in the query, we order the table's entries by the SellStartData field, in reverse. This will make it so the latest items are first, and the oldest items are last.

Run the page, and you should see the three latest products:



Don't be alarmed by the “No Image Available” pictures. Many of the items, unfortunately, don't include real pictures. Instead, they use a “No Image Available” graphic. But at least we know that the ProductPicture.aspx page is properly working.

A New Style

As mentioned earlier, though, the layout of the items is a bit ugly, and the items don't come with any sort of a description beyond a picture. So, let's give the list of items a new style, and let's add more information.

One of the things we'll want to display is the product's category, but to get the name of the category, we need access to the ProductCategory table. Open up AdventureWorks.dbml and drag the ProductCategory table on to the Designer:



Visual Studio associates the tables, and we now have access to the name of the product's category.

Let's add a few classes to our stylesheet:


div.itemBoxSmall

{

 background-color: #F0FFFF; /* Azure */

 border: solid 1px Orange;

 margin: 5px auto 0px auto;

 padding: 5px;

 text-align: left;

 width: 40%;

}


img.productImage

{

 border: solid 1px Black;

 float: left;

 margin-right: 10px;

}


a.productLink

{

 color: Black;

 font-weight: bold;

}


And now let's complete the style by recreating the ItemTemplate to show the new style, as well as a few extra fields:


<ItemTemplate>

 <div class="itemBoxSmall">

 <img src="ProductPicture.aspx?id=<%#Eval("ProductID") %>"

 class="productImage" alt="Image of <%#Eval("Name") %>" />

 <a href="Product.aspx?id=<%#Eval("ProductID") %>" class="productLink">

 <%#Eval("Name") %>

 </a>

 <br />

 Category: <%#Eval("ProductCategory.Name") %><br />

 Color: <%#Eval("Color") %><br />

 List Price: <%#Eval("ListPrice", "{0:C}") %><br />

 </div>

</ItemTemplate>


There, now the list of latest items looks a bit more presentable, and the product's category, color and list price are all displayed, as well as the name of the product. Of course, feel free to add more to it if that suits you.

Preparing to Build the Product Page

Now we can create Product.aspx, the page where the details of an individual product can be viewed. Go ahead and create Product.aspx. Make sure you set MasterPage.master as its master page.

Before we do anything, recall that the description of a product is not in the Product table. Rather, descriptions are associated with models through the ProductModelProductDescription table. So, in order to get the description of an item, we need to first determine a product's model. It's a long trail, though. We need to go from Product to ProductModel to ProductModelProductDescription to ProductDescription. We need to add these tables to AdventureWorks.dbml before we continue with the Product.aspx page:


Now, pay attention to the direction of the arrows, which represent associations. Notice how the arrow between ProductModel and ProductModelProductDescription is pointed away from Product, while every other arrow is pointed toward Product. This is because ProductModel is set as the parent class, and ProductModelProductDescription is set as the child class. Basically, the two terms involve how each table handles the field around which the association is built. With ProductModel and Product, for example, the association is built around ProductModelID. In the ProductModel table, this field is the primary key, and in Product, it's just a normal field. So, ProductModel is the parent class here. However, with ProductModelProductDescription and ProductModel, both tables have ProductModelID as a primary key, so either table can be the parent class.

For our purposes, the association is backward, though. The association suggests that more than one entry in the ProductModelProductDescription table (the child table) can be matched with a given ProductModelID (part of the parent table), just as more than one entry in the Product table can be matched with a given ProductModelID (part of the parent table). It's entirely possible for us to build our application with this configuration, but then to access the ProductDescription for a given Product (p), we have to use First, which is ugly and troublesome:

p.ProductModel.ProductModelProductDescriptions.First().ProductDescription.Description


Fixing this is easy. Click the arrow and delete it to delete the association. Then, right click the Designer and add a new association. Set ProductModelProductDescription as the parent and ProductModel as the child. Then, select the ProductModelID property for both of them:



Now all of the arrows face the same direction:





This makes more sense: while every ProductDescription can be matched with multiple Product entries, every Product can only be matched with one ProductDescription. Now we can drop the call to First when accessing a Product's description:

p.ProductModel.ProductModelProductDescriptions.ProductDescription.
Description

This is a lot more logical.

We're almost ready to begin work on Product.aspx. Just add one final style definition to StyleSheet.css, and we'll be ready to start work:


.itemBoxLarge

{

 background-color: #F0FFFF; /* Azure */

 border: solid 1px Orange;

 margin: 5px auto 0px auto;

 padding: 5px;

 text-align: left;

 width: 70%;

}

Don't forget to check back next week for the third part of this three-part series!

blog comments powered by Disqus
.NET ARTICLES

- .Net 4.5 Brings Changes
- Understanding Events in VB.NET
- Objects, Properties, Events and Methods in V...
- Install Visual Web Developer Express 2010
- Microsoft Gadgeteer an Open Source Alternati...
- Best DotNetNuke Modules
- Facebook Image Viewer in Visual Basic
- Murach`s ADO.NET 4 Database Programming with...
- 5 Must Have Visual Studio 2010 Extensions
- Dynamic Web Applications with ASP.NET Mono u...
- PDFSharp: HTML to PDF in ASP.NET 3.5 using V...
- Using the PDFSharp Library in ASP.NET 3.5 wi...
- Sending Email in ASP.NET 3.5 using VB.NET wi...
- ASP.NET 3.5 Role Based Security and User Aut...
- Creating ASP.NET Login Web Pages and Basic C...

ASP Web Hosting ASP.Net Web Hosting Windows Web Hosting
 
 
 

ASP Free Forums 
 RSS  Tutorials RSS
 RSS  Forums RSS
 RSS  All Feeds
Site Map 
Request Media Kit
Write For Us Get Paid 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Privacy Policy 
Support 


© 2003-2012 by Developer Shed. All rights reserved. DS Cluster 8 - Follow our Sitemap
Most Popular Topics
All ASP.Net Tutorials