完成了配置向导后,该数据集设计器将包含一个强类型的Products DataTable和TableAdapter。让我们花些时间把该DataTable的名称Products改为ProductsOptimisticConcurrency,方法是右键点击DataTable的标题栏,从菜单中选择“重命名”。
图8:一个DataTable和TableAdapter已经添加到类型化数据集
为了看看ProductsOptimisticConcurrency TableAdapter(使用开放式并发)和Products TableAdapter(不使用并发控制)的UPDATE 和 DELETE查询之间有什么不同,选中该TableAdapter并转到属性窗口。在DeleteCommand 和 UpdateCommand 这两个属性的 CommandText 子属性里,我们可以看到调用DAL的update或者delete关联的方法时发送到数据库的实际的SQL语法。ProductsOptimisticConcurrency TableAdapter使用的DELETE语句是
DELETE FROM [Products] WHERE (([ProductID] = @Original_ProductID) AND ([ProductName] = @Original_ProductName) AND ((@IsNull_SupplierID = 1 AND [SupplierID] IS NULL) OR ([SupplierID] = @Original_SupplierID)) AND ((@IsNull_CategoryID = 1 AND [CategoryID] IS NULL) OR ([CategoryID] = @Original_CategoryID)) AND ((@IsNull_QuantityPerUnit = 1 AND [QuantityPerUnit] IS NULL) OR ([QuantityPerUnit] = @Original_QuantityPerUnit)) AND ((@IsNull_UnitPrice = 1 AND [UnitPrice] IS NULL) OR ([UnitPrice] = @Original_UnitPrice)) AND ((@IsNull_UnitsInStock = 1 AND [UnitsInStock] IS NULL) OR ([UnitsInStock] = @Original_UnitsInStock)) AND ((@IsNull_UnitsOnOrder = 1 AND [UnitsOnOrder] IS NULL) OR ([UnitsOnOrder] = @Original_UnitsOnOrder)) AND ((@IsNull_ReorderLevel = 1 AND [ReorderLevel] IS NULL) OR ([ReorderLevel] = @Original_ReorderLevel)) AND ([Discontinued] = @Original_Discontinued))
相反,最初的DAL的Products TableAdapter所使用的DELETE语句则简单得多:
DELETE FROM [Products] WHERE (([ProductID] = @Original_ProductID))
正如你所看到的,启用了开发式并发的TableAdapter所使用的DELETE语句里的WHERE子句包含了对表Product每一个字段现有的值与GridView(或者DetailsView,FormView)最后一次加载时的原始值的对比。因为除了ProductID,ProductName, 和Discontinued之外,其他所有字段都可能为NULL值,所以WHERE子句里还包含了额外的参数以及与NULL值恰当的比较。
在这一节里,我们不会在启用了开放式并发的数据集里增加其他的DataTable了,因为我们的ASP.NET页面将仅提供更新和删除产品信息的功能。然而,我们仍然需要在ProductsOptimisticConcurrency TableAdapter里添加GetProductByProductID(productID) 方法。
为了实现这一点,在TableAdapter的标题栏(在Fill和GetProducts方法名的上方)上右键并从菜单里选择“添加查询”。这将启动TableAdapter查询配置向导。在TableAdapter的最初配置的基础上,选择指定SQL语句来创建GetProductByProductID(productID)方法(见图四)。因为GetProductByProductID(productID)方法返回指定产品的信息,因此需要指定SQL查询类型为“SELECT(返回行)”。
图9:标记SQL查询类型为“SELECT(返回行)”
进入下一步,向导提示我们指定SQL语句,并且与载入TableAdapter默认查询语句。在现有的查询语句的基础上添加WHERE ProductID = @ProductID子句,如图10:
图10:在预载入的查询语句上添加WHERE子句从而返回特定的产品记录
最后,把生成的方法重命名为FillByProductID和GetProductByProductID。
图11:把生成的方法重命名为FillByProductID和GetProductByProductID
完成这个向导之后,现在这个TableAdapter包含两个访问数据的方法:GetProducts(),它返回所有 的产品;和GetProductByProductID(productID),它返回特定的产品。
第三步: 创建一个支持启用了开放式并发的DAL的业务逻辑层