手机版

在ASP.NET 2.0中操作数据68:向数据表添加额外的列

时间:2021-10-30 来源:互联网 编辑:宝哥软件园 浏览:

导言:

向类型化数据集添加TableAdapter时,TableAdapter的主查询已经定义了相应数据表的框架。比如主查询返回A、B、C三个字段,DataTable就会有对应的A、B、C三列,除了主查询之外,TableAdapter还可以包含其他查询,这些查询可能会根据某些参数返回数据。例如,ProductsTableAdapter的主查询返回所有产品的信息。此外,ProductsTableAdapter还包含GetProductByProductID(Categoryid)和getProductID (ProductID)等方法,这些方法根据分配的参数返回特定的产品信息。

如果TableAdapter的方法返回的列包含在主查询中,它将毫无问题地工作。但是,如果返回的列没有包含在主查询中,那么我们需要扩展DataTable的框架。在第35章,《使用Repeater和DataList单页面实现主/从报表》中,我们向CategoriesTableAdapter添加方法,以返回Categoryid、Categoryname、Description和NumberOfProducts列。主查询中涵盖了前三列,但是主查询中没有定义number of product列,它返回与每个类别相关的number of product。我们可以手动向CategoriesDataTable添加一列,以便计算新方法返回的产品数列的值。

在第52章《使用FileUpload上传文件》中,我们讨论了我们应该更加关注TableAdapters,它是通过使用特定的SQL语句构建的,并且其方法返回的列超出了主查询的范围。因为一旦安装向导重新运行,它将更新TableAdapter的方法,以便它返回的列与主查询相匹配。但是,如果使用存储过程,就不会发生这种情况。

在本文中,我们将研究如何扩展DataTable体系结构以包括更多的列。我们都知道使用即席SQL语句框架的TableAdapter是不稳定的。在本文中,我们将使用存储过程作为框架。有关设置TableAdapter使用存储过程的更多信息,请参考第65章,《在TableAdapters中创建新的存储过程》和第66章,《在TableAdapters中使用现有的存储过程》。

步骤1:向产品数据表添加价格四分位列。

在第67章中,我们创建了一个名为NorthwindWithSprocs的类型化数据集,它目前包含两个数据表:ProductsDataTable和EmployeesDataTable。ProductsTableAdapter包含三种方法:GetProducts——主查询返回Products表中的所有记录。getproductbyproductid(categoryID)——根据指定的categoryID值返回所有产品。getproductbyproductid(productid)——根据指定的product id值返回所有产品。

主查询和其他两种方法都返回相同的数据列,即“产品”表的所有列,但不返回“类别”和“供应商”表的相关数据。

在本文中,我们将向ProductsTableAdapter添加一个名为GetProductsWithPriceQuartile的方法,该方法将返回所有产品。除了标准数据列,它还返回PriceQuartile列,该列使用四分位数来衡量产品价格下降的程度。如果产品价格上涨25%,其价值为1。如果降到25%,那么它的值就是4。在我们创建一个存储过程来返回这些信息之前,我们首先需要更新ProductsDataTable,并添加一个新列来包含GetProductsWithPriceQuartile方法返回的PriceQuartile值。

打开NorthwindWithSprocs数据集,右键单击产品数据表,选择添加,然后选择列。

//files.jb51.net/file_images/article/201605/2016051909593832.png

图1:向产品数据表添加一个新列。

这将添加一个名为“Column1”的新列,其类型为System.String。我们需要将该列的名称更改为“PriceQuartile”,其类型更改为System。Int32,因为它的值介于1和4之间。在产品数据表中选择新添加的列,并将其名称属性设置为“价格四分位数”,数据类型属性设置为系统。属性窗口中的Int32。

//files.jb51.net/file_images/article/201605/2016051909593833.png

图2:设置新列的名称和数据类型属性。

如图2所示,我们还可以设置其他属性,比如列的值是否必须唯一;如果列是自增的,是否允许其值为空等。但是,我们在这里使用它的默认值。

步骤2:创建GetProductsWithPriceQuartile方法。

现在我们已经更新了产品数据表以包含价格四分位数列,我们将创建一个带有价格四分位数的GetProductsWithPriceQuartile方法。右键单击表适配器,然后选择添加查询。这将打开TableAdapter查询设置向导。首先,它询问我们是使用即席SQL语句、使用现有存储过程还是创建新的存储过程。我们选择“创建新的存储过程”,然后单击“下一步”。

//files.jb51.net/file_images/article/201605/2016051909593834.png

图3:在TableAdapter向导中创建新的存储过程。

接下来,如图4所示,向导询问我们要添加哪种查询。由于GetProductsWithPriceQuartile方法将返回产品表的所有记录和所有列,因此我们选择项目“选择返回行”,然后单击下一步。

//files.jb51.net/file_images/article/201605/2016051909593835.png

图4:查询将是返回多行的SELECT语句。

接下来,我们在向导中键入以下查询:

选择产品标识、产品名称、供应商标识、类别标识、数量类型标识、单价、单位库存、单位订单、重新订购级别、已停产、超过(4)个(由desc单价订购)作为产品的价格四分之一以上的查询使用SQL Server 2005的新的Ntile函数,该函数将结果分为四组,并按降序对单价值进行分组。

不幸的是,查询生成器无法解析关键字OVER,并抛出一条错误消息。因此,请直接在向导的文本框中键入上述代码,而不要使用查询构造函数。

注:有关NTILE和其他SQL Server 2005功能的更多信息,您可以参考文章《Returning Ranked Results with Microsoft SQL Server 2005》(http://www.4guysfromrolla.com/webtech/010406-1.shtml)和SQL Server 2005联机丛书(http://msdn 2 . Microsoft.com/en-us/library/ms 189798 . aspx)的第《Ranking Functions section》节。

之后,单击“下一步”,向导将重命名新的存储过程。我们将其命名为产品_选择价格四分之一,然后单击下一步。

//files.jb51.net/file_images/article/201605/2016051909594036.png

图5:命名新的存储过程Products _ select with price quartile。

最后,我们要命名TableAdapter的方法,选择“填充一个数据表”和“返回一个数据表”,并将其重命名为FillWithPriceQuartile和GetProductsWithPriceQuartile。

//files.jb51.net/file_images/article/201605/2016051909594037.png

图6:命名TableAdapter的方法,然后单击完成。

指定SELECT查询并命名存储过程和TableAdapter方法后,单击“完成”完成向导。这时,您会看到一两条警告消息,说“不支持over SQL构造函数语句。”不要忽视它。

向导完成后,TableAdapter将包含FillWithPriceQuartile和GetProductsWithPriceQuartile方法,数据库将包含名为Products _ SelectWithPriceQuartile的存储过程。花点时间验证和检查数据库。如果您没有看到我们刚刚添加的存储过程,请右键单击存储过程文件夹并选择刷新。

//files.jb51.net/file_images/article/201605/2016051909594038.png

图7:验证新方法是否被添加到TableAdapter中。

//files.jb51.net/file_images/article/201605/2016051909594039.png

图8:确保数据库包含products _ select with price quartile存储过程。

注意:用存储过程替换即席SQL语句的优点之一是,如果重新运行TableAdapter安装向导,存储过程返回的列将不会更改。我们可以进行验证,右键单击TableAdapter,选择“配置”启动向导,然后单击“完成”完成向导。接下来,我们看一下数据库中的存储过程Products _ SelectwithPriceQuartile。我们注意到它返回的列没有改变。如果我们使用即席SQL语句,重新运行向导将使查询返回的列与主查询的列相匹配,因此它将删除GetProductsWithPriceQuartile方法中使用的查询中的NTILE语句。

当调用数据访问层的GetProductsWithPriceQuartile方法时,TableAdapter将执行Products _ SelectwithPriceQuartile存储过程。并为返回的每条记录向productdatatable添加相应的行。存储过程返回的数据字段将映射到productdatatable的列。因为存储过程返回一个PriceQuartile数据字段,所以它的值将被分配给productdatatable的PriceQuartile列。

对于那些不返回价格四分位数数据字段的方法,价格四分位数列的值由其默认值属性指定。如图2所示,默认值是DBNull。如果要指定其他值,只需更改DefaultValue属性,但它必须是有效值(例如,PriceQuartile列的值必须是System类型的值。Int32)。

现在,我们已经完成了向数据表添加额外列的必要步骤。接下来,我们将创建一个ASP.NET页面来显示每个产品的名称、价格和价格四分位数。但是,我们必须首先更新业务逻辑层,以包含一个方法来调用数据访问层的GetProductsWithPriceQuartile方法。我们将在步骤3中更新业务逻辑层,并在步骤4中创建一个ASP.NET页面。

步骤3:更新业务逻辑层。

在表示层调用新添加的GetProductsWithPriceQuartile方法之前,我们必须在业务逻辑层添加相应的方法,打开ProductsBLLWithSprocs类类文件,并添加以下代码:

[系统。组件模型。component model . DataObjectMethodType . select,false)])公共NorthwindWithSprocs。productdatatable GetProductWithPriceQuartile(){返回适配器。getproductwithpricequartile();}与其他方法一样,getproductwithpricequartile只调用数据访问层对应的getproductwithpricequartile方法并返回其结果。

第四步:在ASP.NET页面显示价格四分位信息。

修改业务逻辑层后,我们将创建一个ASP.NET页面来显示每个产品的价格四分位数信息。在AdvancedDAL文件夹中打开AddingColumns.aspx页,并将GridView控件从工具箱拖到该页。将其标识设置为产品。将其绑定到智能标记中名为ProductsDataSource的新ObjectDataSource控件,将该控件设置为调用ProductsBLLWithSprocs类类的GetProductsWithPriceQuartile方法,并在UPDATE、INSERT和DELETE标记中选择“(无)”。

//files.jb51.net/file_images/article/201605/2016051909594040.png

图9:设置ObjectDataSource来调用ProductsBLLWithSprocs类。

//files.jb51.net/file_images/article/201605/2016051909594041.png

图10:调用GetProductsWithPriceQuartile方法获取产品信息。

完成安装向导后,Visual Studio将为GridView添加边界字段或复选框字段列,包括价格四分位列。除productname、UnitPrice和PriceQuartile之外的所有列都将被删除,并且UnitPrice将被设置为货币格式。单价和价格四分位列将放在右边和中间。最后,这三列的HeaderText属性分别设置为“产品”、“价格”和“价格四分位数”。同时,启用GridView控件的排序功能。

经过上述修改后,GridView和ObjectDataSource控件的声明代码如下所示:

asp3360 GridView ID=' Products ' runat=' server ' alloworting=' True ' AutoGenerateColumns=' False ' DataKeyNames=' Product ID ' data sourceid=' Product data source ' Columns asp: boundfield data field=' Product name ' header text=' Product ' sort expression=' Product name '/asp3360 boundfield data field=' UnitPrice ' data formatstring=' { 0: C } ' header text=' Price ' htmle当然,这些数据也可以根据其他标准进行排序,如图12所示。

//files.jb51.net/file_images/article/201605/2016051909594042.png

图11:产品按价格排序。

//files.jb51.net/file_images/article/201605/2016051909594143.png

图12:产品按名称排序。

注意:只需几个代码,我们就可以根据每行不同的价格四分位值显示不同的颜色,例如值为1的行显示浅绿色,值为2的行显示浅黄色,等等。你可以花一些时间来实现这个功能。如有必要,可以参考第11章,《基于数据的自定义格式化》。

——的另一种方法是创建另一个TableAdapter。

正如我们在本文中看到的,当添加到TableAdapter的方法返回的列超出了主查询的范围时,我们可以将相应的列添加到DataTable中。对于TableAdapter,这种方法只有在它包含很少的方法来返回“额外的列”并且没有太多“额外的列”时才能正常工作。

除了向DataTable添加列,我们还可以向DataSet添加另一个TableAdapter,其中包含需要返回“额外列”的方法。对于这个问题,我们可以向数据集添加另一个名为ProductWithPriceQuartIltableAdapter的TableAdapter。它将products _ selectwithprice四分位数存储过程作为其主要查询。对于想要获取priceQuartile信息的ASP.NET页面,只需要调用productswithpriceQuartile适配器。不需要获取价格四分位数信息的页面只需要调用ProductsTableAdapter。

此外,新添加的TableAdapters可能会导致某些功能和任务重复。例如,如果显示PriceQuartile列的页面也应该启用插入、更新、删除功能,那么,应该正确设置productwithpricequartiletableadapter的insertcommand、updatecommand和deletecommand属性,我们已经设置了ProductsTableAdapter的这三个属性。此时,有两种方法可以添加、更新和删除数据库中的产品。——使用了ProductsTableAdapter类或productswithpricetratileadapter类。

在供下载的代码中,NorthwindWithSprocs数据集包含products switchpricequartiletableadapter类,该类演示了这两种方法。

总结:

在大多数情况下,TableAdapter的所有方法返回的数据列都是相同的,但是很少有方法会返回主查询中没有包含的“额外列”。例如,在第35章,《使用Repeater和DataList单页面实现主/从报表》中,我们向CategoriesTableAdapter添加了一个方法,它不仅返回主查询中的列,还返回了NumberOfProducts列。在本文中,我们考虑向ProductsTableAdapter添加一个方法,以返回主查询中不包含的PriceQuartile列。对于这种“额外列”,我们需要向数据表中添加一个相应的列。

如果您计划手动向数据表添加列,我们建议使用存储过程。如果使用即席SQL语句,每当重新运行TableAdapter安装向导时,用户所做的所有自定义都将被覆盖。但是,如果使用存储过程,就不会发生这种情况。

编程快乐!

作者简介

Scott Mitchell,本系列教程的作者,也是关于ASP/ASP的六本书的作者。NET,是4GuysFromRolla.com的创始人,自1998年以来一直使用微软的网络技术。你可以点击查看所有教程《[翻译]Scott Mitchell 的ASP.NET 2.0数据教程》,希望能帮助你学习ASP.NET。

版权声明:在ASP.NET 2.0中操作数据68:向数据表添加额外的列是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。