第6章 商品属性.docx

上传人:b****5 文档编号:6239766 上传时间:2023-01-04 格式:DOCX 页数:16 大小:924.09KB
下载 相关 举报
第6章 商品属性.docx_第1页
第1页 / 共16页
第6章 商品属性.docx_第2页
第2页 / 共16页
第6章 商品属性.docx_第3页
第3页 / 共16页
第6章 商品属性.docx_第4页
第4页 / 共16页
第6章 商品属性.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

第6章 商品属性.docx

《第6章 商品属性.docx》由会员分享,可在线阅读,更多相关《第6章 商品属性.docx(16页珍藏版)》请在冰豆网上搜索。

第6章 商品属性.docx

第6章商品属性

第6章 商品属性

很多在线商店允许购买者自定义他们购买的商品。

例如,在销售气球时,通常允许顾客自定义气球的颜色等。

本章中,我们将实现产品的属性特征,假定客户端允许顾客下订单时选择气球的颜色。

我们先从数据层开始,在数据层先创建一个数据表和存储过程,然后在业务层中调用该存储过程,最后使用这些功能来修改表示层的组件。

本章的结尾,将允许顾客选择气球的颜色,如图Figure6-1所示。

Figure6-1.Productswithattributes

6.1 实现数据层(ImplementingtheDataTier)

数据层组件支持产品属性特征,包含三个数据表(Attribute,AttributeValue,andProductAttributeValue)以及一个存储过程,名称为GetProductAttributeValues。

三个数据表如下:

•Attribute表存储属性的名称,例如Size或者Color。

•AttributeValue表包含可能的属性值。

在Attribute和AttributeValue数据表之间是一对多的联系。

每一个属性—例如Color—可能有多个和它相联系的值—Red,Orange,Yellow等等。

我们需要该数据表的目的是帮助我们建立从AttributeID(like1forColor)到其可能的值(Red,Orange,Yellow,andsoon)的AttributeValueIDs的链接。

所以,该数据表需要三个字段:

AttributeID对应于Attribute数据表,表示是哪一种属性(例如color或者size);AttributeValueID字段是integer类型,是唯一的标识列(uniquelyidentify);Value字段表示属性的描述文本,例如“Orange,”“Red,”“Small,”“Large,”等等。

•ProductAttributeValue是一个联系表的实现,对应于Product数据表AttributeValue数据表的多对多的联系,该数据表中有字段对(ProductID,AttributeValueID)。

要注意的是,应用不允许产品属性来影响产品的价格。

例如,一个白气球和一个黑气球的价格总是相等的。

若需要不同的产品价格,你需要创建不同的产品。

第5章中通过数据库图表理解了数据表之间的关系。

这些数据表之间的联系的可视化表示如图Figure6-2。

Figure6-2.Diagramdescribingtherelationshipsamongthedatatablesrequiredtoimplement

productattributes

下面我们修改BalloonShop数据库,然后通过练习实现一个新的存储过程CatalogGetProductAttributeValues。

练一练:

为产品属性创建数据层的功能

1.打开SQLServerManagementStudio并执行如下代码,该代码将创建并构造Attribute数据表(你也可以通过VisualWebDeveloper来创建存储过程)。

--ConnecttotheBalloonShopdatabase

USEBalloonShop

--Createattributetable(storesattributessuchasSizeandColor)

CREATETABLEAttribute(

AttributeIDINTIDENTITY(1,1)NOTNULLPRIMARYKEY,

NameNVARCHAR(100)NOTNULL--e.g.Color,Size

--PopulateAttributetable

SETIDENTITY_INSERTAttributeON

INSERTINTOAttribute(AttributeID,Name)

VALUES(1,'Color');

SETIDENTITY_INSERTAttributeOFF

注意:

我们使用SETIDENTITY_INSERTON(注意其中的下划线,原教材上没有),目的是在为数据表添加数据时,可以让我们自己来指定标识列的值。

除了此种情形之外,当一个字段是标识列(IDENTITY)字段时,数据库会为我们自动产生该标识列的ID值。

2.使用如下代码来创建并填充AttributeValuetable数据表:

--CreateAttributeValuetable(storesvaluessuchasYelloworXXL)

CREATETABLEAttributeValue(

AttributeValueIDINTIDENTITY(1,1)NOTNULLPRIMARYKEY,

AttributeIDINTNOTNULL,--TheIDoftheattribute

ValueNVARCHAR(100)NOTNULL--E.g.Yellow

--SettheIDENTITYINSERToptionforAttributeValue

SETIDENTITY_INSERTAttributeValueON;

--PopulateAttributeValuetable

INSERTINTOAttributeValue(AttributeValueID,AttributeID,Value)

SELECT1,1,'White'UNIONALL

SELECT2,1,'Black'UNIONALL

SELECT3,1,'Red'UNIONALL

SELECT4,1,'Orange'UNIONALL

SELECT5,1,'Yellow'UNIONALL

SELECT6,1,'Green'UNIONALL

SELECT7,1,'Blue'UNIONALL

SELECT8,1,'Indigo'UNIONALL

SELECT9,1,'Purple';

--SettheIDENTITYINSERToptionforAttributeValue

SETIDENTITY_INSERTAttributeValueOFF;

3.使用如下的代码创建并填充ProductAttributeValue数据表:

--CreateProductAttributeValuetable(associatesattributevaluesto

products)

CREATETABLEProductAttributeValue(

ProductIDINTNOTNULL,

AttributeValueIDINTNOTNULL,

PRIMARYKEY(ProductID,AttributeValueID)

--PopulateProductAttributeValuetable

INSERTINTOProductAttributeValue(ProductID,AttributeValueID)

SELECTp.ProductID,av.AttributeValueID

FROMproductp,AttributeValueav;

4.执行如下代码,该代码将创建外键并建立Figure6-2所示的数据表之间的联系。

--Createtheforeignkeys

ALTERTABLEAttributeValue

ADDCONSTRAINTFK_AttributeValue_Attribute

FOREIGNKEY(AttributeID)

REFERENCESAttribute(AttributeID)

GO

ALTERTABLEProductAttributeValue

ADDCONSTRAINTFK_ProductAttributeValue_AttributeValue

FOREIGNKEY(AttributeValueID)

REFERENCESAttributeValue(AttributeValueID)

GO

ALTERTABLEProductAttributeValueWITHCHECK

ADDCONSTRAINTFK_ProductAttributeValue_Product

FOREIGNKEY(ProductID)

REFERENCESProduct(ProductID)

GO

注意上面代码中的下划线,原教材中没有。

5.执行如下的SQL代码,将创建CatalogGetProductAttributeValues存储过程。

该存储过程将属性和一个产品相关联。

--CreateCatalogGetProductAttributeValuesstoredprocedure

CREATEPROCEDURECatalogGetProductAttributeValues

(@ProductIdINT)

AS

SELECTa.NameASAttributeName,

av.AttributeValueID,

av.ValueASAttributeValue

FROMAttributeValueav

INNERJOINattributeaONav.AttributeID=a.AttributeID

WHEREav.AttributeValueIDIN

(SELECTAttributeValueID

FROMProductAttributeValue

WHEREProductID=@ProductID)

ORDERBYa.Name;

解释该例是如何工作的:

产品属性的数据逻辑

我们将讨论创建并填充AttributeValue、ProductAttributeValue数据表以及CatalogGetProductAttributeValues存储过程的代码。

在讨论之前,确保你理解了Attribute,AttributeValue,和ProductAttributeValue数据表的每一个字段的含义以及填充这些数据表的代码。

我们先看看AttributeValue数据表。

为了填充该数据表,我们不是使用多个INSERT语句,而是使用INSERT...SELECT语句,该语句将允许我们插入由SELECT语句返回的结果。

然而,我们不是使用简单的SELECT语句来获取数据,我们使用了多个SELECT语句使用了UNIONALL。

总之,我们不是使用如下代码:

--PopulateAttributeValuetable

INSERTINTOAttributeValue(AttributeValueID,AttributeID,Value)

VALUES(1,1,'White');

INSERTINTOAttributeValue(AttributeValueID,AttributeID,Value)

VALUES(2,1,'Black');

INSERTINTOAttributeValue(AttributeValueID,AttributeID,Value)

VALUES(3,1,'Red');...

而是使用如下代码:

--PopulateAttributeValuetable

INSERTINTOAttributeValue(AttributeValueID,AttributeID,Value)

SELECT1,1,'White'UNIONALL

SELECT2,1,'Black'UNIONALL

SELECT3,1,'Red'UNIONALL...

如果你运行SQLServer2008,你可以使用更酷的方式来向数据表中插入多个值。

例如可以使用如下方式:

--PopulateAttributeValuetable--SQLSERVER2008syntax

INSERTINTOAttributeValue(AttributeValueID,AttributeID,value)

VALUES(1,1,'White'),(2,1,'Black'),(3,1,'Red'),...

当填充ProductAttributeValue数据表时,目的是想关联所有已存在属性值(通过AttributeValueID字段)到每一个产品(通过ProductID字段)。

在应用中,我们的产品是气球,我们想销售每一种可能颜色的产品。

填充ProductAttributeValue数据表的代码是使用INSERTINTO命令,该命令插入由SELECT查询得到的很多记录:

INSERTINTOProductAttributeValue(ProductID,AttributeValueID)

在我们的例子中,插入到ProductAttributeValue数据表的SELECT查询是一个交叉连接。

这种连接将产生两个集合的笛卡尔积(Cartesianproduct)。

结果是产生两个数据集的所有可能的组合。

例如,集合{1,2,3}和{a,b,c}的笛卡尔积,在数学上写为{1,2,3}×{a,b,c},将会产生如下的数据集:

{{1,a},{1,b},{1,c},{2,a},{2,b},{2,c},{3,a},{3,b},{3,c}}。

在我们的例子中,如果创建已存在的产品IDs值和已存在的属性值的IDs值的笛卡尔积,我们将获得形式为(ProductID,AttributeValueID)元素的列表,这就是我们想增加到ProductAttributeValue数据表中的记录。

实现该交叉连接的SQL语法是:

INSERTINTOProductAttributeValue(ProductID,AttributeValueID)

SELECTp.ProductID,av.AttributeValueID

FROMproductp,AttributeValueav;

例子数据中包含9个属性值和62个产品。

交叉连接操作将产生558(即9乘以62)条记录到ProductAttributeValue数据表中。

注意使用SELECT语句来创建交叉连接不是标准SQL,虽然这种形式为大多数数据库服务器认可。

正规的实现交叉查询的语法是使用CROSSJOIN语法:

INSERTINTOProductAttributeValue(ProductID,AttributeValueID)

SELECTp.ProductID,av.AttributeValueID

FROMproductpCROSSJOINAttributeValueav;

如果不使用交叉连接(crossjoin),我们也可以使用前面介绍的UNION方法。

UNION将多个SELECT语句的结果累加成一个单独的结果集。

例如,如果将两个各有5条记录的查询进行联合(UNION),结果集将有10条记录。

当然,对于UNION来说,所有的查询必须返回类型相容、数量相同的字段,我们在这里不将详细讨论UNION。

例如,使用UNION,你可以仅仅增加特定的属性值到产品中,如下面的代码所示:

--PopulateProductAttributeValuetable

INSERTINTOProductAttributeValue(ProductID,AttributeValueID)

SELECTProductID,1ASAttributeValueIDFROMproduct

UNIONALLSELECTProductID,2ASAttributeValueIDFROMproduct

UNIONALLSELECTProductID,3ASAttributeValueIDFROMproduct

UNIONALLSELECTProductID,4ASAttributeValueIDFROMproduct

UNIONALLSELECTProductID,5ASAttributeValueIDFROMproduct

UNIONALLSELECTProductID,6ASAttributeValueIDFROMproduct

UNIONALLSELECTProductID,7ASAttributeValueIDFROMproduct

UNIONALLSELECTProductID,8ASAttributeValueIDFROMproduct

UNIONALLSELECTProductID,9ASAttributeValueIDFROMproduct;

最后,我们看看存储过程CatalogGetProductAttributeValues。

该存储过程接受一个参数ProductID,并返回产品属性的列表。

--CreateCatalogGetProductAttributeValuesstoredprocedure

CREATEPROCEDURECatalogGetProductAttributeValues

(@ProductIdINT)

AS

存储过程中的SQL代码返回带有AttributeName,AttributeValueID,andAttributeValue的产品列表:

SELECTa.NameASAttributeName,

av.AttributeValueID,

av.ValueASAttributeValue

FROMAttributeValueav

INNERJOINattributeaONav.AttributeID=a.AttributeID

WHEREav.AttributeValueIDIN

(SELECTAttributeValueID

FROMProductAttributeValue

WHEREProductID=@ProductID)

ORDERBYa.Name;

你可以使用SQLServerManagementStudio来测试该存储过程,用值来替换参数的名字。

例如,你可以用一个产品的ID值来替换参数@ProductID,并执行该存储过程。

相应地,你也可以通过EXEC命令在SQLServerManagementStudio中执行存储过程(如下面的代码片段所示),或者右键点击存储过程在VisualWebDeveloper或者SQLServerManagementStudio中,并选择执行存储过程。

EXECCatalogGetProductAttributeValues1

该命令将返回具有产品ID值为1的结果。

如下图所示。

6.2 实现业务层(ImplementingtheBusinessTier)P207

实现业务层只需要编写调用CatalogGetProductAttributeValues存储过程的代码即可。

增加如下的代码到CatalogAccess类中,在App_Code/CatalogAccess.cs文件中。

//Retrievethelistofproductattributes

publicstaticDataTableGetProductAttributes(stringproductId)

{

//getaconfiguredDbCommandobject

DbCommandcomm=GenericDataAccess.CreateCommand();

//setthestoredprocedurename

comm.CommandText="CatalogGetProductAttributeValues";

//createanewparameter

DbParameterparam=comm.CreateParameter();

param.ParameterName="@ProductID";

param.Value=productId;

param.DbType=DbType.Int32;

comm.Parameters.Add(param);

//executethestoredprocedureandreturntheresults

returnGenericDataAccess.ExecuteSelectCommand(comm);

}

6.3 实现表示层(ImplementingthePresentationTier)

创建表示层的含义是增加相应的控件以允许用户从产品属性列表中选择相应的值。

属性值不是通过硬编码得到的,而是从数据库中读取的,这样在数据库中的属性值修改就可以直接反映到表示层中。

练一练:

实现产品属性表示层

1.将ProductsList.ascx中Price处的代码修改为如下:

Price:

<%#Eval("Price","{0:

c}")%>

PlaceHolderID="attrPlaceHolder"runat="server">

PlaceHolder>

2.增加如下的样式到BalloonShop.css文件中。

.DetailSection{

margin-top:

10px;

margin-bottom:

10px;

}

3.将ProductsList.ascx转换到DesignView,选择DataList控件,打开其属性窗口(使用F4快捷键)。

在属性窗口中选择事件图标,双击ItemDataBound事件实体。

4.增加如下的事件代码。

(注意需要导入System.Data名称空间,方法是在文件的开始位置使用usingSystem.Data;语句)。

usingSystem.Data;

//Executedwheneachitemofthelistisboundtothedatasource

protectedvoidlistItemDataBound(objectsender,DataListItemEventArgse)

{

//obtaintheattributesoftheproduct

DataRowViewdataRow=(DataRowView)e.Item.DataItem;

stringproductId=d

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 党团工作 > 入党转正申请

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1