TableAdapter和多组数据结果

[ 作者 ] Young Joo                                          
       
     很多人问我 TableAdapter 是否能够从存储过程里读取多组数据结果。最直接的回答是:不能。你不能通过 TableAdapter.Fill() 方法来得到一个 Dataset 。但是我们可以通过另一种简单的方法来实现。
 
DataAdapter.Fill()和多组数据结果
 
     TableAdapter.Fill() 方法通过调用 DataAdapter.Fill() 从数据库中读取数据。 DataSet.Fill() 方法可以从存储过程里读取多组数据结果。为了获得多组数据结果,可以应用 DataAdapter.Fill() 的一个重载方法,它将 Dataset 作为参数,这样就可以把存储过程的多组数据结果返回给包含有多个表的 Dataset
    这里,我们通过一个简单的示例来演示一下这种方法是怎样实现的:
    假设在 Northwind 数据库里有一个存储过程 dbo.spSelectCustomersOrders
    CREATE PROCEDURE spSelectCustomersOrders
    AS
    BEGIN 
       SET NOCOUNT ON
       SELECT * FROM Customers 
       SELECT * FROM Orders
    END
   GO
     下面的代码调用了这个存储过程,并且把 2 组数据结果存储在 Dataset 里。
    Dim myConn As New System.Data.SqlClient.SqlConnection
    Dim myAdapter As New System.Data.SqlClient.SqlDataAdapter
    Dim mySelectCommand As New System.Data.SqlClient.SqlCommand
    Dim myDataset As New System.Data.DataSet

    myConn.ConnectionString = "Data Source=.\SQLExpress;Initial Catalog=Northwind;Integrated       Security=True"
    mySelectCommand.Connection = myConn
    mySelectCommand.CommandText = "dbo.spSelectCustomersOrders"
    myAdapter.SelectCommand = mySelectCommand
    myAdapter.Fill(myDataset)

    For Each table As System.Data.DataTable In myDataset.Tables
       Console.WriteLine("Table Name:" & table.TableName)
    Next
    代码的输出形式如下 :
     Table Name: Table
     Table Name: Table1
    
     我们可以看到, DataAdapter.Fill() 方法执行了存储过程,并且把 2 组数据结果分别存储在 2 个数据表里。
 
TableAdapter的解决方案
 
     然而,为什么 TableAdapter.Fill() 方法不能够正确地处理多组数据结果?那是因为 TableAdapter.Fill() 调用的 DataAdapter.Fill() 方法是以 DataTable 作为参数,而不是 Dataset 。这种情况,我们只需要在 TableAdapter 里创建一个新的 Fill 方法,令其调用以 Dataset 为参数的 DataAdapter.Fill() 方法。
     假设这里有一个包含 Customers Orders NorthwindDataset.xsd 文件。让我们用上面的存储过程来实现新的 Fill 方法。把下面的代码加到 partial class 文件里。(在 Dataset Designer 上,可以通过双击或者右键选择 "View Code" 来进入 partial class ,当然也可以手动创建一个空的 class 文件。)
    Namespace NorthwindDataSetTableAdapters
        Partial Public Class CustomersTableAdapter
            Public Function FillCustomersOrders(ByVal dataSet As NorthwindDataSet) As Integer 
                 Dim
multiSelectCommand As New System.Data.SqlClient.SqlCommand 
                 Dim returnValue As Integer 

                 
multiSelectCommand.Connection = Me.Connection 
                 multiSelectCommand.CommandText = "dbo.spSelectCustomersOrders" 
                 Me
.Adapter.SelectCommand = multiSelectCommand 
                 '' Map auto-created Table1 that holds the second result-set (Orders rows) to 
                 '' Orders DataTable in our Dataset. 
                 Me.Adapter.TableMappings.Add("Table1", "Orders"
                returnValue = Me.Adapter.Fill(dataSet) 

                Return
returnValue 
            End Function 
         End
Class
     End
Namespace
      有两点需要特别注意:
      首先,新的 FillCustomersOrders 是以 Dataset 为参数,这样当我们调用 DataAdapter.Fill() 方法时,数据结果就会准确地存储到 Dataset 里。
      第二,注意我们是怎样应用 TableMapping 将自动生成的数据表映射到 Dataset 里的 Orders 表。当应用 DataAdapter.Fill() 来读取多组数据结果,每一组数据结果都被单独地存储在 Dataset 的数据表里。默认情况下,这些数据表被命名为 Table, Table1, Table2… ,为了将这些数据标与 Dataset 里定义的数据表相对应,我们应用 TableMapping 。如果你打开 NorthwindDataset.xsd 后面的代码,在 TableAdapter class InitAdapter() 方法,你就会看到类似的代码:
    tableMapping.SourceTable = "Table"
    tableMapping.DataSetTable = "Customers"
    '' Colum mapping code skipped
     ...
     Me._adapter.TableMappings.Add(tableMapping)
 
      这段代码是为了保证 DataAdapter.Fill 方法返回的数据表与 Dataset 里的数据表相对应。在我们 FillCustomersOrders 示例里,第二组结果包含的是 Orders 信息,所以我们在 Table1 Orders 之间创建了映射关系,确保数据 Fill Orders 表中。
     把以上代码添加到 partial class 后,你就可以调用 FillCustomersOrders 方法来 fill Customers Orders
     CustomersTableAdapter.FillCustomersOrders(Me.NorthwindDataSet)
 
性能的考虑
 
      有些情况下,这种方法的确很有效。但是这也要看情况,也许你会想到这个方法可以避免多次访问数据库,从而提高性能,但如果仅仅只需要获取一小部分数据,却应用这种方法一次读取了大量的数据,这同样也会降低性能,倒不如一次读取小部分数据,需要其它数据时,与数据库建立另一个连接,再读取。 ADO.NET 在处理多个数据库连接方面性能优化得还是不错的,很多情况下,都不至于导致性能瓶颈。总之我们只需要遵循最基本的原则: 只在需要的时候,才去读取数据。
     但有些情况下,读取多组数据结果还是很有帮助的,所以,应用我在这里所介绍的方法吧,但时刻也不要忘记性能的问题。
 
相关资源

 

转载于:https://www.cnblogs.com/coderdream/archive/2009/01/02/1366836.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值