1、Comment s1: 在进行实例开发时可以引入一些软件工程的东西,介绍一下在开发整个网上商店时候的具体步骤,这样读者才能清楚具体一个网站是怎么构建的。下面的例子中,除了创建数据库相关的图不需要更新外,大部分的图都需要更新。第六章 用 LINQ和 MVC开发网上商店s6.1创办网上商店6.1.1给网店取个名灵客我们可以用一整天时间来摆弄各种简单的范例应用,但这些玩意不能帮我们挣钞票。所以,还是来点更有味道的吧,我们来创建一个基于 Web的在线购物车应用,它的名字叫“灵客” 。为什么是购物车呢?因为我们可以从购物车应用上学到很多东西。好吧,我告诉你“购物车”可以展现 ASP.NET开发的很多方面
2、。我们将看到如何创建简单的维护页面、如何连接数据库表、如何处理 Session、以及如何创建表单。在随后的几章中,我们还会谈到一些边缘性主题,例如页面安全等。我们将采用迭代式的方法来开发这个应用程序。我们不打算一开始就弄清楚所有的需求,而是只找出一部分需求,然后立即动手实现这部分功能。所以你找不到专门的章节来讨论数据库分析设计。我们会不断尝试、收集反馈,然后继续进行下一个“设计开发”的小循环。这种开发方式并非总是适用,它要求开发者与用户密切配合,因为开发者在前进的过本章导读 在第四章中我们学习了如何利用 LINQ来进行数据库操作,在第五章中我们学习了用MVC模式来进行 WEB开发。在这一章中,
3、 我们将运用 LINQ和 MVC模式来开发一个实际的项目,网上商店系统。在这个电子商务的时代,相信大部分读者对电子商务都略知一二。在淘宝、当当、易趣等网站的影响下,读者可能有过网购的经历。以前都是在别人的网店上买东西,现在就让我们自己动手来写一个网上商店系统吧。 程中要不断听取用户的反馈。我们可能会犯错,用户也有可能发现自己描述的需求与真实需求有所偏差,这都不要紧我们越早发现自己的错误,改正错误的代价就越小。总而言之,按照这种开发方式,开发过程中会出现很多的变化与修改。我们需要一个强大的工具来随时修改代码以适应我们快速变化的想法。如果我们决定我们需要给数据库的表添加个新列,或修改页之间导航,我
4、们需要能够做到这些,并且不会修改大量代码或配置。当你需要处理这些修改时,ASP.NET MVC Framework 就会大放光芒它的思想是敏捷开发。6.1.2 灵客有什么功能首先,我们要简单记录下灵客网店的大致需求。我们可以从高层面的入手,画出页面之间的流程图。然后,我们要尝试弄清应用程序需要哪些数据(请记住,我们一开始的猜想很可能是错的。 )用例(Use Cases)所谓“用例” ,其实也就是简单的一句话,描述某实体如何使用某系统。灵客网店的用例非常简单。我们首先识别出两个不同的角色(或者叫“参与者” ):买家(buyer)和卖家(seller) 。买家使用灵客网店浏览待售的商品,选择自己要
5、购买的货物,然后提供必要的信息以创建订单。卖家使用灵客网店维护待售的货品列表,确认等待发货的订单,然后将订单标记为“已发货”状态。 (当然,卖家还靠灵客赚很多很多的钱,然后退休,跑到某个热带小岛去安享晚年,不过这就不是本书要考虑的内容了。 )目前,这些就是我们需要的所有细节了。当然,我们可以现在就开始纠缠更多的细节,例如“维护货品列表是什么意思”和“待发货订单由什么组成” 。但为什么要自寻烦恼呢?即使还有尚未明确的细节,在与客户密切合作的迭代过程中,我们也会很快把它们都弄清楚。页面流(Page Flow)小精灵说:我总是想在我的应用程序中有个 main 页的想法,并且让用户大概地知道如何使用它
6、们。在开发的早期,这些页流程还不很全面,但它们还是会帮助我们关注需要做什么和知道事情如何做的次序。有些人想使用 Photoshop,或 Word,或 HTML 来仿制 Web 应用程序的页页流程。我比较喜欢使用笔和纸,因为这个来得更快,而且其他人也可以加入进来,抄起铅笔画出他的想法。Comment s2: 图 6.1 、6.2 没看到在哪里。图 6.1 是我的第一个买方的流程草图,它是很传统的。买方看到一个分类页,从哪里它一次可选择一种产品。每个被选择的产品将添加到购物车中,然后购物车在每次选择之后被显示出来。买方可以使用分类页面继续浏览,或者它付款并买下购物车内的产品。在付款期间我们捕获内容
7、和支付细节,然后显示一个收据页。我们也不知道我们如何处理付款,所以这些细节在流程图中很含糊。图 6.2 显示了卖方的流程,也是相当地简单。在登录后,卖家看见它可以创建或浏览产品的菜单,或者是已发货的定单。一旦浏览一个产品,卖家可以选择编辑产品信息或删除这个商品。“发货”的页面很简单。它显示每个还没有发货的定单,一个订单一页。卖方可以选择跳过下一个,或可以为定单发货,通过使用适当的页信息。在真实世界里,可能我们并不会去处理“发货”这件事情,而且这件事又偏偏是那种可能变得很微妙,微妙得超出你预想的事情。不过,即使现在想得再多,我们也可能会犯错,所以不妨到此为止。等用户亲身体验我们的应用程序之后,我
8、们还来得及再做修改。数据(Data)最后我们需要知道的事是我们用来工作的数据。注意我们没有使用“表结构”或者“类”这样的词汇。我们也没有谈到数据库,表,主键之类的话题。我们只是简单地谈数据。在开发这个舞台上,我们不知道我们会使用什么,有时候一个无格式文件可能比数据库更实用。 在用例和页面流的基础上,我们要处理的数据大概与图 6.3 类似。再一次用笔和纸画些草图。在画数据图的时候,我们遇到了几个问题。既然是在搭建购物车应用,我们肯定需要在首个地方保存商品列表,并且用户可以向其中添加商品,所以我画上了“购物车”(Cart)这一项。但除了用作暂时保存商品列表之外,购物车看起来更像是个幽灵-我想不到有
9、别的东西可以保存在里面。为了反应我的疑惑,我在这个框里打了个问号。我认为,在我们实现灵客网店的过程中,这个疑惑会得到解决。6.1.3 让我们开始吧现在,可以做下来与客户做些初步的分析,我们准备开始开发了!我们将从我们原有的三张图开始工作。但是快速启动它们会是最好的机会因为我们得到反馈时,它们可能会变得过时了。有趣的事,这种方式不会花费我们太长的时间如果你没有花很多时间创建它们话,抛弃的时候就会比较轻松一些。6.2 跑起来再说前面一节我们都是在讲需求,现在让我们先停一下,为了继续进行下去,我们需要做些准备。我们需要创建一个 ASP.NET MVC 应用程序,以及一个数据库,我们随后的工作都将在其
10、中展开。6.2.1 创建 ASP.NET MVC 应用程序在本书第 4 章,我们就已经介绍了如何创建 ASP.NET MVC 应用程序。这里我们就不再重复讲解创建 ASP.NET MVC 应用程序的详细过程,如有不明白的地方请再查阅第 4章相关内容。我们创建了一个名为 eShop 的 ASP.NET MVC 项目,创建完了我们会得到如图 6-4所示的一个目录。(创建完后的解决方案,默认会自动为我们创建一个名为 eShopTests的测试项目。我们在最后会讲到如何使用它,但是目前我们暂且不理会它的存在)图 6-4 灵客网店应用程序文件初始目录6.2.2 创建数据库(SQL Server 安装见附
11、录)在这个应用中,我们将使用 SQL Server 数据库服务器(初学者往往对于安装 SQL Server 感到困惑,如果你不想安装 SQL Server,我们在本书附送的光盘中有 Access 版本的数据库,你可以使用 Access 版本的数据库来进行本书的代码学习,代码基本上是一致的。 )我们首先要打开 SQL Server 管理器,然后在数据库上点击右击,如图所示:图 6-5 创建数据库在右键菜单上,点击“新建数据库” ,将弹出如图所示对话框。填入“eShop”作为数据库名称,然后点击“OK”按钮,数据库即创建完毕。这个时候创建的数据库是一个空的数据库,我们在下面几节应用中会创建一些表,
12、同时还会修改部分表。图 6-6 创建数据库6.2.3 跑起来再说这个时候我们可以来运行看看,虽然我们还没有添加任何东西,但是我们想检查一下我们是否把准备工作做得足够充分。按下 F5,我们会看到如图 6-7 的界面,这证明我们已经准备好了。Comment s3: 需要更新。Beta 版本已经不一样了。图 6-7 ASP.NET MVC应用程序初始界面6.3 商品维护我们第一个开发任务是创建 Web 接口来管理我们的商品信息:创建新商品,编辑现有商品,删除不需要的商品,等等。我们将以最小的迭代来开发这个应用程序,最小意味着以最少的时间来衡量。现在开始吧!6.3.1 创建 Product表我们要进行
13、商品的维护,当然首先得要有一个存储商品的表。之前,我们创建的数据库是空的,现在我们要向数据库添加一个表,名称为 Product。创建 Product表的步骤如下:1) 打开 SQL Server管理器,找到 eShop数据库,如图 6-8所示。2) 在表格上点击右键,然后选择新建数据表。如图 6-9所示3) 之后,将弹出如图 6-10的对话框。填写好我们要创建的字段信息。4) 设置好主键,然后保存为 Product。Comment s4: 6.4.2中一系列图片之后就没有任何解说了,是不是应该再解释详细点。这样读者才能更明白怎么做,做成什么样子。已改6.4.2之后的讲解个人觉得应该多穿插些 M
14、VC的应用。并修改里面的语句使之更适合书名场合。图 6-8 eShop数据库 图 6-9 新建数据表图 6-10 新建 Product数据表 6.3.2 添加 LINQ类创建完数据库后,为了操作数据库以及后面的工作,接下来,我们需要添加 LINQ类,步骤如下:(1)在项目名称上点击右键,选择创建新项目,这时会弹出如图 6-11所示的对话框。图 6-11 选择 ADO.NET Entity Data Model(2)然后选择 ADO.NET Entity Data Model,在下面输入 eShop.edmx,点击确定。此时会弹出图 6-12的对话框让我们选择数据源。图 6-12 选择数据库来源
15、(3)按下一步,进入如图 6-13 的对话框。选择要使用的数据,输入用户名和密码。 (可以使用对话框左下角的测试连接来测试选择的数据库是否可用。)图 6-13 数据库连接创建界面(4)按确定键后,会进入到如图 6-14 所示的界面。在这里你可以选择是否把数据库的用户名和密码存储在配置文件中。如果你不想把你的用户名和密码存储在配置文件中,那就选择 No.然后在下面选上复选框,并填上在配置文件中要使用的名称,这里我们使用 eShopEntities。这里会默认为我们生成一个名称,你可以修改它,但是一般来说你无须修改它。图 6-14 选择数据库连接(5)点击下一步,到图 6-15 的界面,由于我们这
16、个应用中暂时不涉及到视图和存储过程,所以我们只需要将 Tables 打上勾即可,并输入模型的名称 eShopModel。操作完后按完成。至此,我们添加 LINQ 类的工作就完成了。图 6-15 输入模型名称6.3.3 商品维护我们新建一个控制器,名称为 AdminController。让这个控制器来负责处理所有跟商品维护有关的事情(如何创建控制器,请见第 5 章内容) 。需要注意的是,Admin 控制器并不仅处理商品维护,它还要处理其他后台管理中的功能,但是在这一小节,我们暂时只涉及到商品维护。到这里,我们发现目前一切还比较顺利,没有遇到太多的麻烦。但是,新创建的控制器里面只有一个 Index
17、 的方法,这个方法不能满足我们的需要。怎么办?我们只能自己添加方法了。首先,我们需要一个显示商品列表的方法,我们取名为 ProductList。public ActionResult ProductList()这个方法里面什么东西也没有,仍然要我们往里面添加东西。我们需要一个列表,所以添加这两行代码:eShopEntities eshop = new eShopEntities();List products = (from p in eshop.Productselect p).ToList();如果你对这段代码仍然感到疑惑,那么建议你回到第 4 章复习一下 LINQ 的相关内容。List
18、是一种泛型类型,如果现在你对泛型还不清楚,那么没关系,你可以暂时跳过,以后再回头来看,或许你会恍然大悟。另外,这两行代码我们还可以这样写:eShopEntities eshop = new eShopEntities();var products = (from p in eshop.Productselect p).ToList();直接使用 var 关键字来定义,var 关键字是.NET3.5 新增的一个特性:弱类型,严格来说它不是一个类型。所有能用其他类型定义的,都可以 var 类型来定义。这为很多“懒人”提供了便利。有人就会问既然什么类型都可以用 var 来表示,那以后我们是不是都可以
19、不使用强类型来定义了?这是一个很值得思考的问题,需要说明的是 var 并不是万能药,它的方便性是以牺牲性能为代价的。有点类似于装箱和拆箱的操作。在早期的 MVC 版本中,我们需要新建一个新的类,专门来存放所有方法要处理的数据。但是在最新的 Beta 版本中,已经不需要我们手动创建新的类,MVC 已内建了相关的类。我们又回到 ProductList()方法来,我们要把 Controller 中的数据传递给视图,只需要写下面这一行代码即可,这样 ViewData 就能将数据带到视图中去展示。Return View(products);同时,这又向系统说明 ProductList()这个方法要渲染(
20、在 MVC 中,我们一般讲渲染,而不说使用)哪个视图,以及传递哪个 ViewData 过去。做完这些之后,ProductList()方法的整个代码如下:public ActionResult ProductList ()eShopEntities eshop = new eShopEntities();var products = (from p in eshop.Productselect p).ToList();Return View(products);为了让商品列表看上去是按添加时间降序排序的,我们还需要加上一句,最后所以一个比较完整的 ProductList()的代码如下:publi
21、c ActionResult ProductList ()eShopEntities eshop = new eShopEntities();var products = (from p in eshop.Productorderby p.ProductID descendingselect p).ToList();Return View(products);好的,让我们来运行一下看看。啊?怎么会出错呢?图 6-16 出错页面我们来看一下错误信息:视图 ProductList 无法找到。这下终于想起来了,原来我们之前只写了控制器代码,而没有创建相应的视图 ProductList.aspx。为上
22、让后台管理和前台页面整体布局不一样,我们需要创建另外一个母版页(Master Page)。在 Shared 文件夹中新增一个后台管理母版页Admin.Master。Admin.Master 母版页的完整代码如下:灵客网上商店 - 后台管理灵客网上商店 - 后台管理 欢迎你,管理员首页商品管理订单管理退出登录灵客网上商店 Copyright 2008这里我们不打算对这些代码进行仔细的讲解,因为大部分的代码都跟 Site.Master一样,只有少部分修改了一下。下面的视图页面中,我们让所有的前台页面视图都继承于 Site.Mmaster,让所有的后台管理页面视图都继承于 Admin.Master。
23、这样做有便于我们后面代码的维护,同时减少了我们大量的重复代码。关于母版页的使用,本书中不涉及过多介绍,如果想了解更多信息,请参考相关资料。创建完母版面后,我们还要在 View 文件夹下添加一个 Admin 文件夹,然后在Admin 文件夹中添加视图 ProductList.aspx。添加完之后打开ProductList.aspx,我们往里面加点东西:商品管理 (添加商品 )“价格:描述:Comment s5: 此图需要更换新的这是一个 foreach循环语句,每次循环从 ViewData中的 ProductList取出一个商品(Product),然后分别显示商品的名称、价格和描述。然后,我们再
24、按下 F5运行一下。 OK,没错,我们成功了,界面如下:图 6-2 灵客网上商店初始界面但是,怎么会没数据呢?当然没数据了,因为我们还没有往数据库添加过数据,那如何添加数据呢?下面我们来看看,如何往数据库添加一个商品。首先,还是到 AdminController中添加一个方法:AddProduct()。public ActionResult AddProduct()RenderView(“AddProduct“);AddProduct方法用来构建页面,除此之外,我们还需要另外一个方法来保存数据:SaveProduct()。public ActionResult SaveProduct()现在我
25、们往里面添加代码:public ActionResult SaveProduct ()Product product = new Product();product.Name = Request.Form“Name“;product.Description = Request.Form“Description“;product.Price = Convert.ToDecimal(Request.Form“Price“);上面这几行代码的意思就是构建一个 product 对象,然后从表单(下面会提到)中获取数据赋值给 product。但是光是这样写还不行,我们还得把这个 product 添加到数
26、据库中去,下面这两行一定要加上:eshop.AddToProduct(product);eshop.SaveChanges();然后,处理完数据后,我们希望能够自动跳转到 ProductList 页面去,为了达到这个目的,我们还得加上:Return RedirectToAction(“ProductList“);RedirectToAction 有个重载方法,可以传递两个参数:方法名和控制器名,这样我们不仅可以跳转到本控制器的其他方法,还可以跳转到其他控制器的方法去。最后,SaveProduct 方法的全部代码如下:public ActionResult SaveProduct()eShopE
27、ntities eshop = new eShopEntities();Product product = new Product();product.Name = Request.Form“Name“;product.Description = Request.Form“Description“;product.Price = Convert.ToDecimal(Request.Form“Price“);eshop.AddToProduct(product);eshop.SaveChanges();Return RedirectToAction(“ProductList“);细心的读者可能已
28、经发现,这个 SaveProduct 方法和之前的 ProductList 好像有些代码重复了,没错,就是下面这个语句重复了。eShopEntities eshop = new eShopEntities();既然重复了,有没有什么办法能够只写在一个地方,然后其他地方不用再写就可以使用呢?当然有办法。我们可以把这个语句写到一个公共基类里面去,有的读者可能又会有疑问了,为什么要写到另外一个基类中,而不直接写到本类的公共定义去?原因很简单,因为在其他控制器类也会遇到同样的情况,为了最大程度地代码重用,我们建议写到另外一个公共基类中去。因此,我们又需要创建一个控制器基类 ControllerBase
29、.cs,其代码如下 :public class ControllerBase : Controllerpublic eShopEntities eshop = new eShopEntities();然后让 AdminController 控制器和其他控制器类都继承于此基类。其实让所有控制器类都继承于一个基类是有很多好处的,这仅仅是其中很小的一个。后面我们还会提到其他的好处。做完上面这些之后,当然跟显示商品列表一样,我们还需要添加一个 AddProduct 视图。代码如下:商品名称:商品描述:商品价格:首先,我们要添加一个,然后再里面添加商品名称、商品描述、商品价格文本框,当然还有一个提交按钮
30、。按下 F5,运行看一下,界面如下:图 6-2 添加商品页面好的,别高兴得太早,我们要测试一下看是否正确。输入如下信息后按提交按钮。提交之后,我们可以看到列表中已经有我们刚刚添加的商品信息了。图 6-2 商品信息显示界面我们知道如何在数据库表中创建新行;我们创建一个 action,将表单放入视图中,调用模型来保存数据。但是为了让本章变得更有趣一些,让我们使用一点不一样的方式来在控制器中编辑商品信息。在我们用于添加商品信息的代码中,AddProduct() 动作设置了一个表单以编辑产品数据。当表单被用户填好后,它回到控制器中处理一个单独的 SaveProduct() 动作。两个分开的方法一起实现
31、了这部分工作。相反,我们的商品信息修改代码将使用一个动作,EditProduct ()。在这个方法中我们Comment s6: 需要对 EditProduct代码进行讲解,尤其是 RequestType将检测我们是否被调用来显示最初的(空的) 表单,或者是否被调用以保存已填好的表单。我们通过查看引入请求的 HTTP 方法来实现这一点。如果它没有关联的数据,它将是个GET 请求。相反,如果它带有表单数据,我们将看到一个 POST。在 ASP.NET MVC控制器 中,请求信息可以从属性 Request 内获得。我们可以通过方法 RequestType来检查请求类型。这里是文件 SecurityC
32、ontroller中的 AddUser()动作的代码。我们在 AdminController中添加一个 EditProduct的方法。代码如下public ActionResult EditProduct(int id)Product product = (from p in eshop.Productwhere p.ProductID = idselect p).First();ReturnView(product);注意这里我们直接使用 eshop,而没有再对其进行定义了。然后添加一个视图EditProduct.aspx,代码如下:商品详细信息商品名称:商品描述:商品价格:元写完这些之后,
33、读者会想,那从哪个地方去查看呢?是啊,我们把这个页面写好了,但总不能让我去猜每个商品的 ID,然后手动地去输入地址吧。想一想,我们应该在商品列表中给每个商品加个链接,怎么加呢? 很简单,把这行代码换成下面一行就行了。“我们再来浏览一下商品页面,如下图所示,是不是有点变化了图 6-2 商品信息显示界面然后,我们点击一个链接进行看一下,不错,已经实现了我们的要求,可以查看到商品的所有信息了,当然包括价格。如图 6-X 所示。图 6-2 商品详细信息显示页面到这里为止我们一直在做后台商品维护的事情,现在我们要先把这些事情先放一放,我们需要来做一个前台用户可以查看商品的页面。我们新创建一个控制器 Sh
34、opController 用来处理前台所有的功能。 既然要显示那我们肯定需要一个显示商品列表的页面,我们直接在 Index 方法里面来写,代码如下:/ / 商品首页/ public ActionResult Index()var products = (from p in eshop.Productorderby p.ProductID descendingselect p).Take(10).ToList();Return View(products);Index 对应的视图为 View/Shop/Index.axpx,代码如下:商品首页 “价格:描述:别急,到这里还有一些工作需要做,我们还
35、需要一个显示某一个商品详细信息的页面。我们在 ShopController 里加了个 Item()的方法,用来显示某一个商品详细信息,代码如下:/ / 查看某一商品/ / 商品 IDpublic ActionResult Item(int id)Product product = (from p in eshop.Productwhere p.ProductID = idselect p).First();Return View(product);Comment s7: 差一张图对应的视图为 View/Shop/Item.aspx,代码如下:商品详细信息商品名称:商品描述:商品价格:元好了,我
36、们可以运行来检查一下我们刚才的工作。按下 F5,然后在浏览器里输入http:/localhost:端口号/shop ,如果你照着我们这样做,那界面应该是如下这个样子:图 6-x 前台商品首页6.3.4 给 Product表添加字段到目前为止,一切看上去都还不错,可是用户说能不能在每个商品旁边给我加个图片,因为这更直观一些。比起文字性的东西,图片确定更能唤起人们的感觉。所以接下来我们需要为每个商品加个图片。为了达到这个目的,我们需要先给 Product表加个字段 ImageUrl。加完字段后,另忘了更新 eShop.edmx文件。做完了这些工作之后,接下来开始我们对 View/Shop/Inde
37、x.aspx页面进行修改,修改后的页面代码如下:“价格:描述:当然仅仅改了这个视图页面的代码是不够的,因为我们的数据库中虽然新增了 ImageUrl 这个字段,但是还没有相应的数据。所以我们需要回到后台管理页面中去进行一些小修改。我们需要给 AdminController 控制器中的 EditProduct 方法增加一个功能,那就是让我们能够修改商品的 ImageUrl 属性,这点小问题难不倒我们,修改后的 EditProduct()代码如下:/ / 修改商品信息/ / 商品 IDpublic ActionResult EditProduct(int id)Product product =
38、new Product();product = (from p in eshop.Productwhere p.ProductID = idselect p).First();if (Request.RequestType = “POST“)product.Name = Request.Form“Name“;product.Description = Request.Form“Description“;product.Price = Convert.ToDecimal(Request.Form“Price“);Comment s8: 未修改product.ImageUrl = Request.
39、Form“ImageUrl“;eshop.SaveChanges();return RedirectToAction(“ProductList“);return RenderView(product);对应视图修改后的代码如下:修改商品信息“ method=“post“商品名称:“ /商品描述:商品价格:“ /做完上面这些之后,我们就可以在后台进商品信息进行修改 ImageUrl属性,这里我们给每个商品都加上一幅图片。修改完,我们来看一下是否是我们相要的结果,其对应的界面如图 6-x所示:Comment s9: 缺一张图片Comment s10: 需要增加内容图 6-x 修改后的商品列表页面6
40、.4 东西有点乱,来个分类显示到目前为止,今天算得上是成功的一天。我们从客户那里采集了最初的需求、描绘出一个基本的流程、初步整理出所需的数据,并且将用于维护灵客网店中商品信息的页面弄了出来。所以,别放松,进入咱们的第二项任务。我们跟客户讨论了一下优先级的问题, 她希望首先能从买主的角度看到一些东西,所以我们的下一个任务就是搭建一个简单的商品分类显示功能。对我们而言,这项任务同样很有意义:既然已经把货品信息写进了数据库,要显示它们就是小菜一碟。而一旦拥有这个分类显示的功能之后,随后“购物车”那一部分的开发就在此基础上进行。前面“商品维护”中所做的工作现在还能用得上-所谓“分类显示”说穿了就是将“
41、商品列表”界面加以美化。那么,咱们就开始动手吧。6.4.1添加 Category表,更新 LINQ类按照前面的方法,我们在数据库 eShop中添加一个名为 Category的表,用来保存类别相关信息。Category 表很简单,只有两个字段:CategoryID(int)和 Name(Varchar(100)。当然我们还需要在 Product表中增加一个字段 CategoryID用来储存商品所属类别信息。同样与之前做法一样,修改完数据库之后别忘了更新 LINQ类。6.4.2添加分类为了让读者用更少的代码弄懂所有特性,以及减少工作量,我们将不在后台,也就是Comment s11: 未修改Comm
42、ent s12: 未修改Admin控制器中对类别进行维护,我们在初次使用的时候直接写入数据库。我们在数据库中,对 Category表添加了三个分类:图书、数码产品、体育用品。不过,虽然我们不对类别进行维护,但是我们要对商品的类别属性进行维护,也就是说我们要对 EditProduct方法进行修改,以便我们能够修改某一个商品的类别属性。修改后的代码如下:/ / 修改商品信息/ / 商品 IDpublic ActionResult EditProduct(int id)AdminViewData viewData = new AdminViewData();Product product = new
43、 Product();product = (from p in eshop.Productwhere p.ProductID = idselect p).First();if (Request.RequestType = “POST“)product.Name = Request.Form“Name“;product.Description = Request.Form“Description“;product.Price = Convert.ToDecimal(Request.Form“Price“);eshop.SaveChanges();RedirectToAction(“Product
44、List“);viewData.Product = product;RenderView(“EditProduct“, viewData);同时我们还要对视图文件进行修改,也就是要加上一个选择商品类别的语句,修改后的代码如下:修改商品信息“ method=“post“商品名称:“ /商品描述:商品价格:“ /做完这些之后,由于之前我们在输入商品信息的时候没有输入商品的类别信息,所以这时候我们需要对个商品设置一下类别属性。6.4.3 分类显示商品在后台做好准备工作后,我们把目光转移到前台显示商品列表上来。我们要对之前简单的商品列表进行调整,以便能够方便地查看某一个类别的商品。所以,我们得在 ShopController 中新增加一个方法:Category()。目的是用来显示某一个类别下的所有商品,其代码如下:/ / 分类显示商品列表/ / 类别 IDpublic ActionResult Category(int id)var products = (from p in eshop.Productwhere p.Category.CategoryID = idselect p).ToList();return View(products);