第4章 创建商品目录

演示了 新表的创建,主键的创建,外部关键字的约束,利用数据库关系图来显示和管理外键的约束,实现多对多的关系。

利用存储过程在数据层实现分页,这是性能最高的一种分页方式,原理如下:

在SQL2005中支持对结果集的行进行编号,这样我们要取出结果中6到10条的记录就可以这样写:

--申明临时表变量@Products
declare @Products TABLE
(RowID int,
ProductID int,
Name nvarchar(50),
Description nvarchar(1000))

--向临时表赋值
insert into @Products
select row_number() over (order by productid) as rowid, productid,name,description from product

--从临时表中取数据
select productid,Name,Description FROM @Products
where rowid>=6 and rowid<=10

实际应用在获取分类中商品的存储过程代码如下:

create procedure GetProductInCategory
(@CategoryID INT,
@DescriptionLength INT,
@PageNumber INT,
@ProductsPerPage INT,
@HowManyProducts INT OUTPUT)
AS 

DECLARE @Products TABLE
(RowID INT,
ProductID INT,
Name NVARCHAR(
50),
Description NVARCHAR(
1000),
Price Money,
Img1File NVARCHAR(
50),
Img2File NVARCHAR(
50),
OnSub1Promotion bit,
OnCatalogPromotion bit
)

INSERT INTO @Products
SELECT ROW_NUMBER() OVER (ORDER BY Product.ProductID),Product.ProductID,Name,SUBSTRING(Description,
1,@DescriptionLength) +'' AS Description,
Price,Img1File,Img2File,OnSub1Promotion,OnCatalogPromotion FROM Product INNER JOIN ProductCategory
ON Product.ProductID
=ProductCategory.ProductID
WHERE ProductCategory.CategoryID
=@CategoryID

SELECT @HowManyProducts 
= COUNT(ProductID) FROM @Products

SELECT ProductID,Name,Description,Price,Img1File,Img2File,OnSub1Promotion,OnCatalogPromotion
FROM @products
WHERE RowID
>(@PageNumber-1)*@ProductsPerPage AND RowID<=@PageNumber*@ProductsPerPage

获取某个大类下推荐的商品列表的存储过程GetProductOnSub1Promotion:

create procedure GetProductOnSub1Promotion
(@Sub1ID INT,
@DescriptionLength INT,
@PageNumber INT,
@ProductsPerPage INT,
@HowManyProducts INT OUTPUT)
AS 

DECLARE @Products TABLE
(RowID INT,
ProductID INT,
Name NVARCHAR(
50),
Description NVARCHAR(
1000),
Price Money,
Img1File NVARCHAR(
50),
Img2File NVARCHAR(
50),
OnSub1Promotion bit,
OnCatalogPromotion bit
)

INSERT INTO @Products
SELECT ROW_NUMBER() OVER (ORDER BY ProductID) AS Row,ProductID,Name,SUBSTRING(Description,
1,@DescriptionLength) +'' AS Description,
Price,Img1File,Img2File,OnSub1Promotion,OnCatalogPromotion FROM 
(SELECT DISTINCT Product.ProductID,Product.Name,SUBSTRING(Product.Description,
1,@DescriptionLength)+'' AS Description,Price,Img1File,Img2File,OnSub1Promotion,OnCatalogPromotion
FROM Product INNER JOIN ProductCategory ON Product.ProductID
=ProductCategory.ProductID
INNER JOIN Category ON ProductCategory.CategoryID
=Category.CategoryID
WHERE Product.OnSub1Promotion
=1
AND Category.Sub1ID
=@Sub1ID)
AS ProductOnSub1Pr

SELECT @HowManyProducts 
= COUNT(ProductID) FROM @Products

SELECT ProductID,Name,Description,Price,Img1File,Img2File,OnSub1Promotion,OnCatalogPromotion
FROM @products
WHERE RowID
>(@PageNumber-1)*@ProductsPerPage AND RowID<=@PageNumber*@ProductsPerPage

嗯 这样的支持分页的存储过程代码性能很不错 不过只有SQL2005支持。接下来是业务层的编码, 其功能呢个只是调用数据层的存储过程。里面提到了使用结构类型,他是一个值类型,比引用类型如类效率要高。

表示层主要是编写用户控件,这里要注意的是,控件里如果是用的ASP.NET语法,则需要使用相对路径,因为控件是存放在/UserControls子目录下的,如

<asp:HyperLink ID="HyperLink1" Runat="server" NavigateUrl='<%# "../Catalog.aspx?Sub1ID="+Request.QueryString["Sub1ID"]+"&CategoryID=" + Eval("CategoryID") %>'

但如果是使用HTML语法,就不需要使用相对路径了,可以理解为是类似于shtml方式的<!--#include file=""-->嵌入,比如:

<asp:DataList ID="list" Runat="server" RepeatColumns="2">
<ItemTemplate>
<class="ProductName" href='Product.aspx?ProductID=<%# Eval("ProductID")%> '><%# Eval("Name"%></a>

在表示层中最大的挑战是实现翻页链接,为了获取URL中QueryString的参数并且再加上page页码的参数组合成新的url查询参数,程序引用了

using System.Collections.Specialized;

对前一页PreLink和NextLink的链接赋值如下:

        if (howManyPages > 1)
        {
            
int currPage = Int32.Parse(page);
            pagingLabel.Visible 
= true;
            preLink.Visible 
= true;
            nextLink.Visible 
= true;
            pagingLabel.Text 
= "" + page + "页,共" + howManyPages.ToString() + "";
            
if (currPage == 1)
                preLink.Enabled 
= false;
            
else
            {
                NameValueCollection query 
= Request.QueryString;
                
string paramName, newQueryString = "?";
                
for (int i = 0; i < query.Count; i++)
                    
if (query.AllKeys[i] != null)
                        
if ((paramName = query.AllKeys[i].ToString()).ToUpper() != "PAGE")
                            newQueryString 
+= paramName + "=" + query[i] + "&";
                preLink.NavigateUrl 
= Request.Url.AbsolutePath + newQueryString + "Page=" + (currPage - 1).ToString();
            }

            
if (currPage == howManyPages)
                nextLink.Enabled 
= false;
            
else
            {
                NameValueCollection query 
= Request.QueryString;
                
string paramName, newQueryString = "?";
                
for (int i = 0; i < query.Count; i++)
                    
if (query.AllKeys[i] != null)
                        
if ((paramName = query.AllKeys[i].ToString()).ToUpper() != "PAGE")
                            newQueryString 
+= paramName + "=" + query[i] + "&";
                nextLink.NavigateUrl 
= Request.Url.AbsolutePath + newQueryString + "Page=" + (currPage + 1).ToString();
            }
        }
原文地址:https://www.cnblogs.com/hulu/p/1364643.html