在ASP.NET 2.0中操作数据之六十六:在TableAdapters中
在Visual Studio环境中,我们经常会使用TableAdapter来与数据库进行交互,实现数据的增删改查。有时我们需要使用已存在的存储过程来满足特定的业务需求。本文将详细介绍如何在Visual Studio中手动添加存储过程,并配置TableAdapter来使用这些存储过程。
导言
在之前的文章中,我们已经了解了如何通过TableAdapter向导自动生成存储过程。但在实际开发中,我们往往需要根据实际需求使用已存在的存储过程。由于Northwind数据库中现有的存储过程可能不足以满足我们的所有需求,我们还需要知道如何在Visual Studio环境中手动向数据库添加新的存储过程。
第一步:向Northwind数据库添加存储过程
向数据库添加存储过程非常简单。在Visual Studio的“服务器资源管理”窗口中,展开Northwind数据库,你会看到“存储过程”文件夹中列出了所有的存储过程。要添加新的存储过程,只需右键点击“存储过程”文件夹,选择“添加新存储过程”。
例如,我们可以添加一个名为`Products_SelectByCategoryID`的存储过程,该过程接受一个`CategoryID`作为输入参数,并返回与该`CategoryID`匹配的所有产品。在打开的脚本窗口中,输入如下T-SQL代码:
```sql
CREATE PROCEDURE dbo.Products_SelectByCategoryID
(
@CategoryID int
)
AS
SELECT ProductID, ProductName, SupplierID, CategoryID, QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued FROM Products WHERE CategoryID = @CategoryID
```
执行该脚本后,新的存储过程`Products_SelectByCategoryID`就会被添加到数据库中。保存脚本后,刷新存储过程文件夹,你将看到新添加的存储过程。
第二步:设置TableAdapter使用现有的存储过程
当存储过程被添加到数据库后,我们需要配置TableAdapter来使用这些存储过程。在Visual Studio中,可以通过以下步骤来完成这一操作:
1. 打开你的数据访问层项目。
2. 在“数据源”窗口中,找到你的数据表(例如,“Products”)。
3. 右键点击数据表,选择“更新数据表”。
5. 配置完成后,点击“确定”。TableAdapter就会使用你指定的存储过程来完成相应的数据库操作。
通过这种方式,我们可以灵活地配置TableAdapter来使用已存在的存储过程,以满足特定的业务需求。这不仅提高了开发效率,还使得代码更加清晰和易于维护。接下来,我们将向ProductsTableAdapter添加一个新的方法GetProductsByCategoryID(categoryID),以便根据特定的产品类别ID检索产品。这个过程涉及对数据的深层次操作,需要我们精确地在数据访问层(DAL)和业务逻辑层(BLL)之间配置交互。
在NorthwindWithSprocs数据集中,我们需要对ProductsTableAdapter进行配置。通过右键单击ProductsTableAdapter并选择“添加查询”,启动TableAdapter Query Configuration wizard。在这里,我们将使用先前创建的存储过程Products_SelectByCategoryID。
在配置过程中,选择“使用现有存储过程”选项,并继续下一步。接下来的界面会展示一个包含所有数据库存储过程的下拉列表。从列表中选择Products_SelectByCategoryID存储过程。
紧接着,系统将会询问存储过程的返回类型。由于我们的存储过程Products_SelectByCategoryID是返回某个特定类别的所有产品,因此我们需要选择“表数据(Tabular Data)”选项。这样,TableAdapter的方法将返回一个ProductsDataTable实例。
随后,我们需要定义方法的名称和模式。这里我们将采用填充数据表(Fill a DataTable)的模式,并将方法重命名为GetProductsByCategoryID和FillByCategoryID。这样,在DAL层我们就完成了GetProductsByCategoryID方法的设置。
值得注意的是,我们在设置这些方法时,需要传递一个int类型的输入参数,即@CategoryID。如果我们需要更改Products_SelectByCategory存储过程的参数,也必须相应地更新这些TableAdapter方法的参数。这可以通过手动添加或删除参数集里的参数,或者运行TableAdapter向导来完成。
完成DAL层的配置后,我们需要在业务逻辑层(BLL)添加相应的方法来调用DAL层的方法。打开ProductsBLLWithSprocs类文件,并添加如下方法:
```csharp
[SystemponentModel.DataObjectMethodAttribute(SystemponentModel.DataObjectMethodType.Select, false)]
public NorthwindWithSprocs.ProductsDataTable GetProductByCategoryID(int categoryID)
{
return Adapter.GetProductsByCategoryID(categoryID);
}
```
这个BLL层的方法通过调用ProductsTableAdapter的GetProductsByCategoryID()方法来返回一个ProductsDataTable。通过这种方式,我们在业务逻辑层和数据访问层之间建立了桥梁,使得数据的检索和交互更为便捷和高效。整个过程中,我们保持了操作的连贯性和流畅性,确保了应用程序的健壮性和易用性。在编程世界中,通过整合DataObjectMethodAttribute属性,我们在使用ObjectDataSource设置数据源向导时,能更加流畅地实现数据交互。这尤其在ASP.NET开发中展现出了极大的优势。接下来,让我们以展示产品为例,详细阐述这一过程。
为了测试新添加的Products_SelectByCategoryID存储过程以及DAL和BLL层中的相应方法,我们创建一个ASP.NET页面。这个页面包含两个核心控件:一个DropDownList控件和一个GridView控件。
DropDownList控件在这里扮演着关键角色,它列出了数据库中的所有类别。当用户选择某个特定的类别时,GridView控件会即时更新,展示属于该类别的所有产品。这种交互方式极大地提升了用户体验。
在开发过程中,我们打开ExistingSprocs.aspx页面,位于AdvancedDAL文件夹内。我们从工具箱拖出一个DropDownList控件到页面,设置其ID为Categories,并将AutoPostBack属性设置为true。为了获取类别数据,我们绑定它到一个名为CategoriesDataSource的ObjectDataSource控件。这个控件调用CategoriesBLL class类的GetCategories方法。在UPDATE、INSERT和DELETE操作中,我们选择不进行任何操作,保持默认设置为"(None)"。
完成ObjectDataSource向导后,我们设置DropDownList控件以显示CategoryName列,同时传递的Value值为CategoryID列。该控件与ObjectDataSource控件的代码看起来非常专业且高效。
接下来,我们在DropDownList控件旁边放置一个GridView控件,将其ID设为ProductsByCategory。这个GridView控件需要绑定到另一个ObjectDataSource控件,名为ProductsByCategoryDataSource。这个控件将调用ProductsBLLWithSprocs class类的GetProductsByCategoryID(categoryID)方法,专门用于获取特定类别的产品。由于这个GridView控件只用于展示数据,所以在UPDATE、INSERT和DELETE操作上同样选择不进行任何操作。
在设置ObjectDataSource控件的参数时,我们选择参数来源为“Control”,并在ControlID下拉列表中选择“Categories”。这样设置后,当用户在DropDownList控件中选择一个类别时,该categoryID参数会自动传递给GetProductsByCategoryID(categoryID)方法,从而实时更新GridView展示的内容。
Visual Studio在完成ObjectDataSource向导后会自动为GridView添加必要的BoundFields列以及一个CheckBoxField列,以提供额外的功能或交互性。这一系列操作确保了数据的动态展示和交互的流畅性。通过这样的设置,我们成功地将数据库中的产品和其所属类别信息动态地展示在ASP.NET页面上,为用户提供了直观且高效的信息浏览体验。走进技术的前沿,一个令人耳目一新的体验正等待着你。你是否想过,一个网站可以如此智能,可以根据你的选择和喜好,展示你所关心的内容?今天,我们来一个神奇的网站,它的界面可以根据你的选择,展示出不同的产品类别。
想象一下,你正在浏览一个饮料类产品的网站。只需在浏览器里登录该页面,轻轻一点击“Beverages”,屏幕上便会展示出琳琅满目的饮料类产品。如果你对其他类别感兴趣,比如“Produce”,只需轻轻一点,所有相关的产品就会立刻呈现在你的眼前,如图12所示。
现在,让我们跨越到数据库的世界,如何在存储过程中使用事务来管理数据。在第61章中,我们了如何使用事务对数据库修改命令进行封装,确保数据的完整性和一致性。事务中的命令要么全部成功执行,要么全部失败回滚。这种技术包括使用System.Transactions命名空间里的类,以及在数据访问层(DAL)调用ADO.NET classes类(如SqlTransaction)。
而在本章中,我们将学习如何在存储过程里运用T-SQL事务命令来管理事务。手动启动、提交、回滚事务的3个主要SQL命令是BEGIN TRANSACTION、COMMIT TRANSACTION和ROLLBACK TRANSACTION。在一个存储过程里使用事务时,通常采取以下模式:
1. 指出事务已经开启
2. 执行事务包含的SQL语句
3. 如果第二步的任何语句出错,则回滚事务
4. 如果第二步的所有语句执行无误,则提交事务
这一模式可以用T-SQL语法来执行。例如:
```sql
BEGIN TRY
BEGIN TRANSACTION -- 开始事务
... 执行事务包含的SQL语句 ...
-- 如果我们到达这里,表示成功!
COMMIT TRANSACTION
END TRY
BEGIN CATCH
-- 出错啦!
ROLLBACK TRANSACTION
-- 抛出带有异常详细信息的错误
DECLARE @ErrMsg nvarchar(0), @ErrSeverity int
SELECT @ErrMsg = ERROR_MESSAGE(), @ErrSeverity = ERROR_SEVERITY()
RAISERROR(@ErrMsg, @ErrSeverity, 1)
END CATCH
```
这段代码采用TRY...CATCH模式——SQL Server 2005新增的结构。就像C中的try...catch模式一样,SQL的TRY...CATCH模式在TRY块中执行语句。如果任何语句出错,会立即跳转到CATCH块。
如果执行无误,COMMIT TRANSACTION将提交更改并完成事务;如果执行出错,那么CATCH块的ROLLBACK TRANSACTION将数据库恢复到开始前的状态。存储过程还会通过RAISERROR命令抛出一个SqlException异常。需要注意的是,TRY...CATCH模式是SQL Server 2005中新增的,如果你使用的是较旧版本的Microsoft SQL Server,上述代码可能无法执行。你可以参考《Managing Transactions in SQL Server Stored Procedures》这篇文章寻求帮助。
让我们通过一个实际例子来更深入地了解这一技术。在这个例子中,我们将展示如何在一个存储过程中使用TRY...CATCH模式和事务管理来确保数据的完整性和一致性。这将是一个充满挑战和机遇的旅程,让我们一同这个充满魔力的世界!在数据库管理中,数据表之间的关联关系是非常重要的,特别是在处理如“Categories”和“Products”这样的表时。在这两者之间存在一个外键约束,确保数据的完整性和关联性。简单来说,这意味着“Products”表中的“CategoryID”列的值必须和“Categories”表中的“CategoryID”值相匹配。
想象一下,如果某个分类(Category)下有对应的产品(Product),而我们尝试直接删除这个分类,系统将会因为无法找到相匹配的产品分类ID而阻止这一操作,这就是外键约束的作用。为了更直观地展示这一过程,让我们登录到~/BinaryData/UpdatingAndDeleting.aspx这个页面。
如图13所示,每一个分类(Category)的记录都附带编辑(Edit)和删除(Delete)按钮。当你尝试删除一个有对应产品的分类,比如“Beverages”时,由于外键约束的存在,删除操作将会失败,如图14所示。
我们的目标是能够删除任何分类,无论其是否有关联的产品。当需要删除分类时,我们同样希望删除其相关联的产品,或者将这些产品的“CategoryID”设置为NULL。为了实现这一目标,我们可以创建一个存储过程。这个存储过程将接受一个输入参数@CategoryID,用于标识需要处理的分类。
在数据库操作中,有时我们需要删除某个分类及其相关的产品。为了实现这一功能,我们可以创建一个名为“Categories_Delete”的存储过程。该过程的主要任务是先删除与该分类相关的所有产品,然后再删除该分类本身。让我们深入了解这一过程的具体实现。
人们可能会想到创建一个类似于狼蚁网站SEO优化策略的存储过程。该存储过程的目的是确保数据库操作的流畅性和效率。以下是创建该存储过程的SQL脚本:
```sql
CREATE PROCEDURE dbo.Categories_Delete
(
@CategoryID int
)
AS
BEGIN TRY
BEGIN TRANSACTION -- 开始事务处理
-- 删除与该分类相关的所有产品
DELETE FROM Products WHERE CategoryID = @CategoryID;
-- 然后,删除该分类本身
DELETE FROM Categories WHERE CategoryID = @CategoryID;
-- 如果成功执行到这里,则提交事务
COMMIT TRANSACTION
END TRY
BEGIN CATCH
-- 如果出现错误,则回滚事务
ROLLBACK TRANSACTION
-- 捕获异常信息并抛出错误提示
DECLARE @ErrMsg nvarchar(0), @ErrSeverity int;
SELECT @ErrMsg = ERROR_MESSAGE(), @ErrSeverity = ERROR_SEVERITY();
RAISERROR(@ErrMsg, @ErrSeverity, 1);
END CATCH;
```
在添加了“Categories_Delete”存储过程后,数据访问层(DAL)就可以使用此存储过程来执行删除操作了。但在此之前,我们需要更新CategoriesTableAdapter,使其能够调用新创建的存储过程。值得注意的是,在前几章中我们处理的是包含单个实体——ProductsDataTable的NorthwindWithSprocs数据集。现在,我们需要处理与分类相关的操作。当我们要删除某个分类时,CategoriesTableAdapter会调用“Categories_Delete”存储过程来执行删除操作。通过这种方式,我们可以确保数据库操作的原子性和一致性。这也提高了数据库操作的效率和性能。通过创建和使用存储过程,我们可以更好地管理和控制数据库操作,从而确保数据的准确性和完整性。在Visual Studio的世界里,数据库操作是个既重要又复杂的部分。让我们深入一下Northwind数据集里的CategoriesTableAdapter。通过它,我们能够更直观地理解如何通过编程删除数据并处理数据库事务。这是一种非常直观且功能强大的工具,能够让你更深入地理解数据访问层(Data Access Layer,DAL)。如果你指的是我们在第一章里创建的Northwind数据集,那么以下的讨论就是基于那个数据集进行的。
当你打开Northwind数据集,并选中CategoriesTableAdapter时,属性窗口就会展现出它的面貌。这个窗口列出了该TableAdapter所拥有的InsertCommand、UpdateCommand、DeleteCommand以及SelectCommand等命令,以及相关的数据库连接信息。展开DeleteCommand属性,你会发现其细节如图15所示。这里的DeleteCommand的ComamndType属性被设置为Text,这意味着它是一个即时执行的SQL查询。
图15展示了如何在CategoriesTableAdapter的属性窗口查看其属性信息。我们可以对其进行一些修改来提升效率。选中DeleteCommand文本后,在下拉列表中选择“(New)”,这将清除掉CommandText、CommandType和Parameters属性的设置。然后,将CommandType属性设置为StoredProcedure。接着,在CommandText属性里输入存储过程的名称(即dbo.Categories_Delete)。按照这种顺序设置的话,Visual Studio会自动生成Parameters collection(参数集)。如果没有按照这个顺序来设置的话,你可能需要手动添加参数。无论哪种方式添加参数,我们都应该打开Parameters Collection Editor对话框以检查参数是否正确,如图16所示。在这个对话框里,如果没看到任何参数,那么就需要手动添加参数@CategoryID等。不需要添加参数@RETURN_VALUE。这个过程对于理解数据访问层的工作方式至关重要。当你完成这些步骤后,删除一个category将自动删除所有与之相关的产品,所有这些操作都在一个事务中完成。为了确保数据安全,建议在测试Categories_Delete存储过程前对数据库进行备份。测试完毕后,可以使用备份的数据库文件恢复数据。虽然TableAdapter向导可以自动生成存储过程,但在某些情况下我们需要使用现有的存储过程。我们学习了如何在Visual Studio环境中手动添加存储过程,并引导TableAdapter使用这些存储过程的方法。同时我们也了解了如何在存储过程中使用T-SQL命令和脚本模式来开启、提交和回滚事务。这些技能将帮助你在编程道路上走得更远。祝编程快乐!本文的作者是Scott Mitchell,他是ASP/ASP.NET领域的专家,自1998年以来一直在应用微软Web技术。如果你对ASP.NET的学习有任何疑问或需要进一步的指导,不妨查阅他的一系列教程《》,这些教程对你的学习将大有裨益。
平面设计师
- 在ASP.NET 2.0中操作数据之六十六:在TableAdapters中
- WPF图形解锁控件ScreenUnLock使用详解
- 浅谈PHP实现大流量下抢购方案
- JavaScript实现搜索框的自动完成功能(一)
- javascript实现根据3原色制作颜色选择器的方法
- apply和call方法定义及apply和call方法的区别
- 用FSO获得图片文件的信息(大小,宽,高)
- perspective是什么意思
- PHP控制反转(IOC)和依赖注入(DI)
- JS基于Ajax实现的网页Loading效果代码
- PHP设计模式之建造者模式定义与用法简单示例
- 完美实现js焦点轮播效果(二)(图片可滚动)
- 如何理解潇洒的深层含义
- PHP生成二维码与识别二维码的方法详解【附源码
- 纯javascript实现四方向文本无缝滚动效果
- bootstrap为水平排列的表单和内联表单设置可选的