ASP.NET 2.0数据教程之六十九:在TableAdapter里使用JOINs

返回“ASP.NET 2.0数据教程目录”

导言:

在关系数据库里,我们处理的数据通常跨越了几个数据表。举 例:当展示产品信息时我们很可能想列出每个产品相应的category以及供应商的 名称等.诚然,Products表里包含有CategoryID 和SupplierID值,但是事实上的 category以及supplier names分别定义在Categories表和Suppliers表里. 要从其 它的相关表里获取信息,我们可以使用correlated subqueries或JOINs.一条 correlated subquerie就是一个镶套的SELECT,引用外部查询(outer query)的列 .比如在第一章《Creating a Data Access Layer》里我们在 ProductsTableAdapter的主查询里使用2条correlated subqueries来返回每个产 品的category 以及supplier names.而JOIN是一SQL构造,将2个不同的表的相关 联的rows进行合并.在第47章《Querying Data with the SqlDataSource Control 》里,我们使用JOIN来显示每个产品的category信息.

我们避免在 TableAdapters里使用JOIN是由于TableAdapter向导自动生成的INSERT, UPDATE, 以及DELETE statements有其局限性.具体来说,如果TableAdapter的主查询里包 含了任何的JOIN,那么TableAdapter就不能为它的InsertCommand, UpdateCommand,以及DeleteCommand属性自动地创建 ad-hoc SQL statements或存 储过程.在开始之前,我们先简要地对correlated subqueries和JOIN进行比 较.

比较Correlated Subqueries和JOINs

我们知道在第一章的 Northwind DataSet数据集里创建的ProductsTableAdapter使用correlated subqueries来返回每个产品对应的category 和 supplier name。该 ProductsTableAdapter的主查询如下:

SELECT ProductID, ProductName, SupplierID, CategoryID,
    QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder,
    ReorderLevel, Discontinued,
    (SELECT CategoryName FROM Categories WHERE Categories.CategoryID =
      Products.CategoryID) as CategoryName,
    (SELECT CompanyName FROM Suppliers WHERE Suppliers.SupplierID =
      Products.SupplierID) as SupplierName
FROM Products

我们注意这2个correlated subqueries——“(SELECT CategoryName FROM Categories WHERE Categories.CategoryID = Products.CategoryID)” 以及“ (SELECT CompanyName FROM Suppliers WHERE Suppliers.SupplierID = Products.SupplierID),都是一个SELECT查询,返回一个单一值,并作为外部 SELECT statement的额外的列.

此外,我们可以使用JOIN来返回每个产品 的supplier 以及category name,下面的查询与上面的代码效果一样,不过用的 是JOIN:

SELECT ProductID, ProductName, Products.SupplierID, Products.CategoryID,
    QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder,
    ReorderLevel, Discontinued,
    Categories.CategoryName,
    Suppliers.CompanyName as SupplierName
FROM Products
  LEFT JOIN Categories ON
    Categories.CategoryID = Products.CategoryID
  LEFT JOIN Suppliers ON
     Suppliers.SupplierID = Products.SupplierID

JOIN基于某种标 准将一个表的记录与另一个表的记录合并起来.比如上述代码中,“LEFT JOIN Categories ON Categories.CategoryID = Products.CategoryID”就 指示SQL Server将每一条product记录与category记录合并起来,标准是category 记录的CategoryID值与product记录CategoryID值相吻合.在合并的结果里,我们 可以对每个产品相应的category fields进行处理(比如CategoryName).

时间: 2024-11-03 16:11:57

ASP.NET 2.0数据教程之六十九:在TableAdapter里使用JOINs的相关文章

ASP.NET 2.0数据教程之六十八:在TableAdapters里使用现有的存储过程

返回"ASP.NET 2.0数据教程目录" 导言: 在前面的文章里我们考察了如何让TableAdapters向导自动的创 建存储过程.而在本文,我们将考察如何让TableAdapter使用现有的存储过程.由 于Northwind数据库现有的存储过程很少,我们也需要考察如何在Visual Studio 环境里手动向数据库添加新的存储过程. 注意: 在第63章 <Wrapping Database Modifications within a Transaction>里我们向

ASP.NET 2.0数据教程之六十二:创建一个用户自定义的Database-Driven Site Map

返回"ASP.NET 2.0数据教程目录" ASP.NET 2.0数据教程之六十二:创建一个用户自定义的Database-Driven Site Map Provider 导言: ASP.NET 2.0的网站地图(site map)功能允许页面开发者在一些 持久介质(persistent medium),比如一个XML文件里,自己定义一个web程序的 site map.一旦定义了之后,我们可以通过System.Web命名空间的SiteMap class 类或某个Web导航控件,比如Si

ASP.NET 2.0数据教程之六十六:批添加数据

返回"ASP.NET 2.0数据教程目录" 导言: 在前面的第64章<Batch Updating>里,我们用GridView控件 里定制了一个批编辑界面,同样的我们也可以定制一个批添加界面.假设有这种情 况,我们接受一批从Tokyo(东京)发过来的货物:6种不同的tea 和 coffee,如果 用户在一个DetailsView控件里一次输入一个产品,他将会重复的输入很多相同的 值,比如相同的种类(Beverages),相同的供应商(Tokyo Traders),相同的 d

ASP.NET 2.0数据教程之六十五:批删除数据

返回"ASP.NET 2.0数据教程目录" 导言: 在前面的教程,我们用GridView创建了一个批编辑界面.在用户需 要一次性编辑多条记录的情况下,批编辑界面很有用.同理,当用户需要同时删 除多条记录时,该技术也很有用. 如果你使用过邮件系统的话,你应该对 这种最常见的批删除界面很熟悉:界面里每一行都包含一个checkbox,此外,还 有一个"Delete All Checked Items"按钮(如图1).本教程比较短, 因为我们在前面的教程已经完成大体的框架,

ASP.NET 2.0数据教程之六十四:批更新数据

返回"ASP.NET 2.0数据教程目录" 导言: 在前面的教程,我们对数据访问层进行扩展以支持数据库事务. 数据库事务确保一系列的操作要么都成功,要么都失败.本文我们将注意力转到 创建一个批更新数据界面. 在本文,我们将创建一个GridView控件,里面 的每一行记录都可以进行编辑(见图1),因此我们没有必要多添加一列来包含 Edit, Update,和Cancel按钮,而是在页面包含2个"Update Products"按钮,被点击时,遍历所有的产品并对数据库进

ASP.NET 2.0数据教程之六十:在程序启动阶段缓存数据

返回"ASP.NET 2.0数据教程目录" 导言: 前面2章考察了在表现层和缓存层缓存数据.在第58章,我们探 讨了在表现层设置ObjectDataSource的相关cache属性来缓存数据.在第59章,我 们探讨了创建一个单独的分开的缓存层.这2章都是采用"应激装载" (reactive loading)的模式来缓存数据.该模式下,每次请求数据时,系统先 检查其是否在内存,如果没有,则从数据源--比如数据库,来获取 数据,然后将其存储在内存里.该模式的优势在于执行

ASP.NET 2.0数据教程之四十九:使用SqlDataSource插入、更新以及删除数据

返回"ASP.NET 2.0数据教程目录" 导言 在概述插入.更新和删除数据中我们讨论过,GridView控件提供 了内建的更新与删除功能,而DetailsView和FormView控件除了这些之外还拥有插 入功能.这些数据修改功能可以直接接入到数据源控件中而不需要编写任何代码 .概述插入.更新和删除数据讲解了如何使用ObjectDataSource来帮助GridView .DetailsView以及FormView控件完成插入.更新以及删除操作. ObjectDataSource能工

ASP.NET 2.0数据教程之六十七:在TableAdapters里创建新的存储过程

返回"ASP.NET 2.0数据教程目录" 导言: 本教程的Data Access Layer (DAL)使用的是类型化的数据集 (Typed DataSets).就像我们在第一章<Creating aData Access Layer>里探讨 的一样,该类型化的数据集由强类型的DataTable和TableAdapter构成. DataTable描绘的是系统里的逻辑实体而TableAdapter引用相关数据库执行数据访 问,包括对DataTable填充数据.执行返回标量数

ASP.NET 2.0数据教程之六十三:在事务里对数据库修改进行封装

返回"ASP.NET 2.0数据教程目录" 导言: 正如我们在第16章<概述添加.更新.删除数据>里探讨的那 样,GridView控件内建的功能支持对每行数据的编辑和删除功能,你只需要稍稍 动一下鼠标就可以创建丰富的数据修改界面而不用写一行代码.但是,在某些情况 下,这还不够,我们需要让用户能够成批地处理数据. 比如,很多基于 web(web-based)的电子邮件客户端,将所有邮件出来,每条邮件除了包含邮件信 息(主题.发送者等)外,还包含一个checkbox控件.这些界