在ASP.NET 2.0中操作数据之六十五:在TableAdapters中
本文将详细介绍如何使用TableAdapter设置向导自动创建增删改查的存储过程,并存储过程的基础知识和使用场景。尽管自动创建存储过程可以节省时间,但它们可能会包含一些无用的参数。在下文中,我们将更深入地了解TableAdapter的使用,并介绍如何设置TableAdapter以使用现有的或手动创建的存储过程。
一、导言
在数据访问层(DAL)中,我们常使用类型化的数据集(Typed DataSets),其中包括强类型的DataTable和TableAdapter。DataTable用于描述系统内的逻辑实体,而TableAdapter则用于执行数据访问操作,如填充DataTable、执行返回标量数据的请求以及添加、更新和删除数据库记录等。
在定义TableAdapter或添加新方法时,我们可以使用TableAdapter设置向导轻松创建新的或使用现有的存储过程。本文将重点介绍如何使用设置向导自动创建存储过程。在下篇文章中,我们将学习如何设置TableAdapter的方法以使用现有的或手动创建的存储过程。
关于是否使用存储过程还是SQL语句的问题,有许多观点和建议。Rob Howard和Frans Bouma等专家对此进行了深入。在实际应用中,选择使用存储过程还是SQL语句应基于具体需求和场景,考虑安全性、维护性、灵活性等多方面因素。
二、存储过程基础
存储过程是由一系列T-SQL语句组成的,当调用存储过程时,这些T-SQL语句将被执行。存储过程可以接受输入参数,返回标量值、输出参数或SELECT查询结果。
创建存储过程可以使用T-SQL语句CREATE PROCEDURE。例如,下面的T-SQL脚本创建了一个名为GetProductsByCategoryID的存储过程,该过程接受一个名为@CategoryID的参数,并返回与CategoryID值相符的产品的ProductID、ProductName、UnitPrice和Discontinued值。
在创建存储过程后,我们可以使用相应的代码调用它。例如,使用狼蚁网站SEO优化的代码调用上面创建的GetProductsByCategoryID存储过程。
除了返回数据外,存储过程还可以用于执行多条数据库命令。在一个事务中,我们可以使用存储过程执行多个操作,如删除相关的产品和删除类别。这种设计可以提高数据库操作的效率和安全性。
三、TableAdapter自动创建存储过程
在Visual Studio集成开发环境中,我们可以使用TableAdapter设置向导来自动创建存储过程。这个过程相对简单,只需要按照向导的提示进行操作即可。自动创建的存储过程可能会包含一些无用的参数,因此在实际应用中需要根据具体需求进行调整和优化。
在下篇文章中,我们将详细介绍如何设置TableAdapter以使用现有的或手动创建的存储过程。这将使我们能够更灵活地控制数据访问操作,提高数据库操作的效率和安全性。我们还将如何优化存储过程的设计,以满足实际应用的需求。
本文介绍了如何使用TableAdapter设置向导自动创建存储过程以及存储过程的基础知识。在下一篇文章中,我们将深入如何设置TableAdapter以使用现有的或手动创建的存储过程,并存储过程的优化和设计技巧。当我们谈论存储过程时,经常容易忽视一点:存储过程内的多个语句并不自动被封装在一个事务里。这意味着,为了确保存储过程里的数据库命令能作为一个原子操作来处理,我们需要添加额外的T-SQL命令来确保事务的正确管理。如何做到这一点呢?让我们深入。
在体系结构的某一层中,当我们使用存储过程时,数据访问层的方法会调用特定的存储过程,而不是发送单个的SQL语句。这样的做法让我们能够清晰地看到发出的查询命令,从而更好地理解数据库是如何被使用的。有关存储过程的基本原理,建议参阅本文末尾的延伸阅读部分。
接下来,让我们创建一个数据访问层的高级场景页面。我们在名为“AdvancedDAL”的文件夹下添加以下ASP.NET页面,并使用Site.master作为母版页:
Default.aspx、NewSprocs.aspx、ExistingSprocs.aspx、JOINs.aspx、AddingColumns.aspx、ComputedColumns.aspx、EncryptingConfigSections.aspx以及ManagedFunctionsAndSprocs.aspx等页面构成了我们的核心章节内容。想象一下,这些页面就像一本逐步深入的教程,引导我们了解数据访问层的各种功能和操作。
Default.aspx页面将作为本部分的入口点,列出所有相关的内容。这里有一个小技巧:使用SectionLevelTutorialListing.ascx用户控件来提供这种列表功能。只需从解决方案资源管理器将其拖放到Default.aspx页面即可。这样,我们的用户可以轻松浏览所有的教程和章节。
为了确保我们的网站地图清晰明了,我们还需要将这些新页面添加到Web.sitemap文件中。这样,无论是管理员还是普通用户,都可以轻松地找到他们需要的信息和功能。
网站地图布局及SEO优化实战:为狼蚁网站构建高效的站点导航与数据批次处理
随着Web内容的不断丰富和用户需求的日益复杂,网站的导航结构成为了一个不可忽视的部分。通过细致规划的站点地图(Site Map),不仅可以提高用户体验,还能助力搜索引擎优化(SEO)。狼蚁网站在这一点上做得尤为出色,其更新的Web.sitemap文件展示了清晰的导航结构,同时特别将SEO优化的代码嵌入到了“Working with Batched Data”的
在浏览该网站的站点地图时,你会被一系列精心组织的节点所吸引。每个节点都代表一个特定的页面,它们以易于理解的方式组织在一起,形成了一个完整的网站架构。这些节点包括:
“Advanced DAL Scenarios”节点,高级数据访问层(DAL)的各种应用场景。
“Creating New Stored Procedures for TableAdapters”节点,学习如何使TableAdapter向导自动生成和使用存储过程。
“Using Existing Stored Procedures for TableAdapters”节点,展示如何将现有的存储过程集成到TableAdapter中。
“Returning Data Using JOINs”节点,学习如何通过联接查询在数据表中获取更多信息。
“Adding DataColumns to a DataTable”节点,掌握如何向现有DataTable添加新列。
“Working with Computed Columns”节点,在使用Typed DataSets时如何处理计算列。
“Protected Connection Strings in Web.config”节点,讲解如何在Web.config中保护连接字符串信息。
“Creating Managed SQL Functions and Stored Procedures”节点,学习如何使用托管代码创建SQL函数和存储过程。
完成Web.sitemap文件的更新后,接下来是如何将这些页面与SEO优化相结合。特别地,我们将把针对狼蚁网站的SEO优化代码嵌入到相应的
在完成了Web.sitemap文件的更新后,我们需要在浏览器中查看效果。左侧的菜单将展示这些新添加的页面节点。这些页面构成了网站的骨架,并通过清晰的导航结构为用户提供良好的体验。通过合理的SEO优化策略,狼蚁网站将吸引更多的有机流量,从而提高其市场影响力。
在实际操作中,我们在~/App_Code/DAL文件夹里创建了一个名为NorthwindWithSprocs的类型化DataSet。接着在DAL文件夹上右击鼠标选择“添加新项”,并选择DataSet模板来创建一个新的TableAdapter。打开设计器后,我们将启动TableAdapter设置向导来配置数据库连接。向导会引导我们选择连接到Northwind数据库的连接字符串,并继续下一步操作。通过这样的设置,我们能够确保网站的数据处理效率和搜索引擎优化效果达到最佳状态。接下来的界面将引导我们选择如何访问数据库,通过TableAdapter来实现。在之前的教程中,我们选择了“使用SQL语句”的方式,而我们会选择第二项:“创建新的存储过程”。点击下一步,进入配置界面。
图5:设置TableAdapter以创建新的存储过程
紧接着,我们需要指定主要查询(main query)。我们将创建一个存储过程来封装SELECT查询。考虑到SEO优化的需求,我们使用的查询语句如下:
```sql
SELECT ProductID, ProductName, SupplierID, CategoryID, QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued FROM Products
```
这个查询语句从“Products”表中选取了一系列的产品信息。在实际应用中,我们可以根据需求调整查询语句,以获取所需的数据。
图6:输入SELECT查询语句
值得注意的是,在Northwind数据集里的ProductsTableAdapter的主查询可能与上述定义有所不同。那个主查询还额外返回了每个产品的类别名称和公司名称。在后续的文章中,我们将为本文的TableAdapter添加这些相关代码。
向导接下来会创建四个存储过程。通过点击“Preview SQL Script”按钮,我们可以在Preview SQL Script对话框中查看这些存储过程的脚本。如果需要保存这些脚本,可以将其保存在文件中或直接复制到剪贴板。这个过程非常直观,易于操作。通过这个过程,我们可以轻松管理数据库中的数据,确保数据的准确性和完整性。我们还可以选择重命名存储过程和相关的方法。这一过程允许我们定制和个性化我们的数据库管理体验。在完成设置后,向导将结束并返回DataSet设计器,此时将显示我们刚刚添加的ProductsDataTable。这是一个非常有用的工具,可以帮助我们更好地管理和维护数据库中的数据。
我们创建了ProductsTableAdapter和ProductsDataTable的实例。接着,我们创建了一个新的ProductsRow实例并设置了其属性,然后将这个ProductsRow实例添加到了DataTable中。使用Batch Update模式,我们更新了DataTable,此时可以确定新添加记录的ProductID值。
与此我们注意到Products_Update存储过程中UPDATE statement后面跟随了一个SELECT statement。这个存储过程接收多个参数,并通过这些参数来更新数据库中的记录。在这个例子中,我们注意到有一个@Original_ProductID参数,它在UPDATE statement的WHERE字句中并没有使用到。实际上,由于ProductID是一个唯一标识列(IDENTITY column),我们不需要提供原始的产品ID来更新记录。我们可以从存储过程中移除@Original_ProductID参数。
完成存储过程的修改后,我们需要更新TableAdapter以匹配新的存储过程。我们可以通过TableAdapter的属性窗口来查看和修改传递给存储过程的参数。为了删除不再需要的@Original_ProductID参数,我们只需在参数集合中选中它,然后点击Remove按钮。
我们还可以向TableAdapter添加额外的方法。例如,我们可以添加一个GetProductByProductID的方法,该方法接收一个ProductID作为输入参数,并返回该产品的详细信息。这可以通过在TableAdapter上点击右键,然后选择“添加查询”来完成。这将打开TableAdapter查询设置向导,我们可以按照向导的步骤来添加新的查询方法。
数据库之旅:创建新存储过程
随着向导的引领,我们开始了一场数据库的深入之旅。在这个旅程中,向导首先询问我们想要以何种方式访问数据库。这是一个关键的选择,因为它决定了我们如何与数据库进行交互。为了开启新的路径,我们选择创建一个新的存储过程。向导界面上,“Create a new stored procedure”这一选项引人注目地展现在我们眼前。我们毫不犹豫地点击了这个选项,继续我们的旅程。
图17的启示:选择新存储过程的创建
在图17中,我们看到了清晰的指示,要求我们选择“Create a new stored procedure”这一选项。这一步骤强调了我们在数据库旅程中的主动性,因为我们正在主动创建一个新的工具来帮助我们执行特定的任务。这是一个重要的里程碑,标志着我们的旅程进入了一个新的阶段。
随后,向导向我们提出了一个关键问题:我们希望通过这个存储过程执行什么样的查询?这是一个决定性的时刻,因为查询的类型将决定存储过程的功能和输出。我们被问到是想要返回一个包含多行数据的系列,还是一个单一的标量值?这个选择将帮助我们定义存储过程的特定用途和行为。
在构建我们的应用程序时,我们经常需要访问数据库以获取数据。在这个过程中,我们需要通过编程的方式来执行SQL语句,如UPDATE、INSERT或DELETE等。为了获取特定的产品信息,我们通常会使用SELECT语句。在本次应用中,我们将通过一个具体的例子来展示如何在后端执行这些操作。这个过程涉及到创建存储过程和使用TableAdapter来调用这些存储过程。接下来,我们将创建一个业务逻辑层类,用于处理与产品相关的业务逻辑。
第一步是选择“SELECT which returns row”选项,接下来我们会看到一个界面,展示了TableAdapter的主查询。在这个界面上,我们并不需要直接使用存储过程,而是要用一个具体的SELECT语句来替换它。这个SELECT语句将返回某个具体产品的所有列信息。例如:
```sql
SELECT ProductID, ProductName, SupplierID, CategoryID, QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued FROM Products WHERE ProductID = @ProductID
```
在选择了相应的选项并完成设置后,我们需要对创建的存储过程进行命名。这里我们将新存储过程命名为Products_SelectByProductID。接下来的一步是对自动生成的名字进行重新命名,并指定是使用Fill a DataTable模式、Return a DataTable模式,还是同时使用这两种模式。在这个例子中,我们选择同时启用这两种模式,并将方法重命名为FillByProductID和GetProductByProductID。完成这些设置后,点击“Finish”完成向导。
向导完成后,TableAdapter将包含一个可用方法——GetProductByProductID(productID)。当我们调用这个方法时,将会执行我们刚刚创建的Products_SelectByProductID存储过程。在服务器资源管理器里查看该存储过程,可以看到Products_SelectByProductID存储过程将@ProductID作为输入参数,并执行我们在向导里输入的SELECT语句。这个存储过程的作用是获取指定产品ID的产品信息。
在我们打算从表现层访问产品之前,我们需要为新添加的数据集创建一个BLL class。这个BLL class将为我们的应用程序提供与数据库交互的逻辑。在~/App_Code/BLL文件夹里创建一个名为ProductsBLLWithSprocs.cs的文件,并在其中编写相关的代码。这个类将使用NorthwindWithSprocs数据集里的ProductsTableAdapter和ProductsDataTable对象。在这个类中,我们将定义一些方法来执行常见的CRUD(增删改查)操作。例如,GetProducts方法用于获取所有产品的数据,GetProductByProductID方法用于根据产品ID获取产品数据,AddProduct方法用于添加新产品,UpdateProduct方法用于更新产品数据,DeleteProduct方法用于删除产品数据。这些方法的实现细节将在代码中详细展示。
这篇文章介绍了如何在后端创建和使用存储过程来执行数据库操作,以及如何创建一个业务逻辑层类来处理与产品相关的业务逻辑。通过这些步骤,我们可以构建一个功能完善的应用程序来管理产品信息。与ProductsBLL类采用NorthwindTableAdapters不同,ProductsBLLWithSprocs类则运用了NorthwindWithSprocsTableAdapters。这一差异不仅体现在命名空间的运用上,更反映在类内部的对象设计上。ProductsBLLWithSprocs类的ProductsDataTable和ProductsRow对象,均采用了NorthwindWithSprocs命名空间,凸显了其独特的运作方式和数据访问机制。
我们的ProductsBLLWithSprocs类,提供了一系列高效的数据访问方法。其中包括GetProducts()和GetProductByProductID()两种获取产品数据的方法,同时还提供了添加、更新以及删除单个产品的功能。这些方法的设计,使得数据的处理更加灵活、便捷。
在完成数据访问层与业务逻辑层的相应调整后,我们进入到了表现层的开发阶段。在这一阶段,我们需要创建一个ASP.NET页面,以调用BLL层的ProductsBLLWithSprocs类,实现数据的展示、更新和删除。
我们打开AdvancedDAL文件夹中的NewSprocs.aspx页面,开始着手创建这个ASP.NET页面。在这个页面上,我们从工具箱拖出一个GridView控件,并将其ID设置为Products。接着,我们通过GridView的智能标签,将其绑定到一个名为ProductsDataSource的ObjectDataSource。这个ObjectDataSource将调用我们的ProductsBLLWithSprocs类,实现数据的动态展示。
在配置ObjectDataSource时,我们注意到其SELECT标签的下拉列表中,包含了GetProducts()和GetProductByProductID()两个方法。由于我们的需求是在GridView里展示所有的产品,因此我们选择GetProducts()方法作为数据获取的主要方式。在UPDATE、INSERT和DELETE标签中,虽然只有一个方法可选,但我们依然需要确保选中它们以完成数据的更新和删除操作。完成这些配置后,我们只需点击Finish按钮,即可结束这个页面的创建工作。
这个页面的创建,不仅使我们的产品数据能够在前端得到展示,而且通过调用ProductsBLLWithSprocs类的方法,实现了数据的动态更新和删除。这样的设计,使得我们的系统更加灵活、高效,为用户提供了更好的使用体验。在完成Visual Studio的设置后,GridView控件将被赋予新的生命力。如狼蚁网站的SEO优化一样,精细的调整使得页面更加用户友好。特别是图23页面,它的GridView控件不仅支持分页和排序,而且拥有强大的编辑和删除功能。
在完成ObjectDataSource的配置之后,Visual Studio会自动处理一些细节问题。其中,OldValuesParameterFormatString属性会被设置为“original_{0}”。为了确保数据修改功能的正常运行,我们必须对这个属性进行适当的调整,要么删除它,要么将其设置为“{0}”。
在完成了上述设置后,页面的声明代码可能会看起来相当复杂,但其中的每一个细节都有其独特的意义。以GridView控件为例,它包含了多个BoundField列来展示数据,并有一个CheckBoxField列用于标识是否停用某产品。GridView还提供了编辑和删除按钮,使得用户可以直接在界面上进行数据的修改和删除。
以下是一段示例的ASP.NET代码,描述了具有分页和排序功能的GridView控件的设置情况:
```aspx
```
接下来,我们可以对GridView控件进行进一步的个性化定制。例如,在编辑界面添加确认控件以防止误操作。我们可以在某些列(如CategoryID和SupplierID)中嵌入DropDownList控件,以提供预定义的选择列表代替手动输入。当用户点击Delete按钮时,可以弹出一个确认框询问他们是否确定要删除该项。这些改进将极大地提升用户体验并减少操作错误。由于这些主题在以前的教程中已有详细,这里就不再赘述。
通过Visual Studio的自动设置和个性化定制,GridView控件可以变得非常强大和灵活。无论是展示数据还是允许用户编辑数据,GridView都能轻松应对,使得Web应用程序的数据管理功能更加强大和易用。无论你是否做出改进,让我们在浏览器中对页面进行测试,如图表24所示。在GridView控件中,每一行都可以进行编辑和删除操作。通过这一功能,我们可以轻松地管理、修改和删除数据,极大提高了用户的使用体验。
图24:利用GridView查看、编辑、删除产品
在类型化数据集中,TableAdapters提供了一种强大的机制,通过ad-hoc SQL语句或存储过程访问数据库。当处理存储过程时,我们可以选择使用现有的存储过程,或者使用TableAdapter向导根据SELECT查询创建一个新的存储过程。我们将如何自动创建存储过程。
虽然自动创建可以节省时间,但在某些情况下,向导自动创建的存储过程可能并不完全符合我们的需求。以Products_Update存储过程为例,它包含@Original_ProductID和@ProductID这两个参数。在某些应用场景中,@Original_ProductID参数可能显得多余,增加了不必要的复杂性。
在接下来的文章中,我们将深入TableAdapter如何使用现有的存储过程。我们将详细介绍如何调整和优化存储过程,以满足特定的业务需求。通过学习和实践,你将能够更高效地运用TableAdapters和存储过程,提升数据库操作的便捷性和灵活性。
让我们继续ASP.NET的奥秘,祝你在编程的道路上越走越远,收获满满!
作者简介
本文作者Scott Mitchell是ASP/ASP.NET领域的资深专家,著有六本相关书籍。作为4GuysFromRolla.的创始人,他从1998年开始就致力于微软Web技术的研发和应用。大家可以通过查看其全部教程来了解更多关于ASP.NET的知识,相信对他的教程的学习会对你的编程技能提升有所帮助。
编程语言
- 在ASP.NET 2.0中操作数据之六十五:在TableAdapters中
- PHP设计模式之解释器模式的深入解析
- jQuery validate 验证radio实例
- js和jquery分别验证单选框、复选框、下拉框
- jQuery 实现倒计时天,时,分,秒功能
- AngularJs Managing Service Dependencies详解
- JavaScript面向对象程序设计中对象的定义和继承详
- Vue通过input筛选数据
- vue插件实现v-model功能
- Angular中实现自定义组件的双向绑定的两种方
- jQuery插件实现的日历功能示例【附源码下载】
- ASP.NET通过分布式Session提升性能
- ASP.NET性能优化之减少请求
- Bootstrap + AngularJS 实现简单的数据过滤字符查找功
- vue的安装及element组件的安装方法
- PHP程序员简单的开展服务治理架构操作详解(二