返回单行实体的数据操作

发布日期: 4/1/2004 | 更新日期: 4/1/2004

使用 .NET 构建分布式应用程序

Priya Dhawan

Microsoft Developer Network

2002 年 2 月修订

摘要: 本文涵盖了使用 ADO .NET 返回单行实体的数据操作。(14 页打印页)

请下载 Bdadotnet.msiBdadotnet_beta2.msi

本页内容
简介简介
返回数据的操作返回数据的操作
使用 Output 参数获取单个值使用 Output 参数获取单个值
使用 ADO .NET DataReader 对象使用 ADO .NET DataReader 对象
使用 ADO .NET SQLCommand 对象和 XmlReader使用 ADO .NET SQLCommand 对象和 XmlReader
使用 ADO .NET DataSet 对象使用 ADO .NET DataSet 对象
写操作写操作
使用 ADO .NET Command 对象使用 ADO .NET Command 对象
使用 ADO .NET DataAdapter 对象使用 ADO .NET DataAdapter 对象
小结小结

简介

ADO .NET 提供各种执行返回单行数据实体的查询和修改该数据的方法。本文将讨论这些使用 ADO .NET SQL 托管提供程序的技术。

返回数据的操作

SQL 表达式中来自 “选择” 语句的数据可以使用 ADO .NET “命令” 对象、DataReader 对象或 “数据集” 对象上的 Output 参数返回。

使用 Output 参数获取单个值

ADO .NET Command 对象提供了名为 ExecuteScalar 的方法以从数据库检索单个值。此方法执行查询并返回由该查询返回的结果集中的第一行的第一列。结果集可以包含多行,ExecuteScalar 忽略这些行。

下面的示例使用 Command 对象的 ExecuteScalar 方法从数据库检索单个值。

Dim sqlConn As SqlConnection
Dim sqlCmd As SqlCommand
Dim param As SqlParameter
Dim orderStatus As Integer
Try
   'Create a new connection object
   sqlConn = New SqlConnection(Common.getConnectionString)
   'Create a new command object
   sqlCmd = New SqlCommand()
   'Specify the stored procedure and connection
   With sqlCmd
      .CommandType = CommandType.Text
      .CommandText = _ 
"Select OrderStatus from Orders Where OrderId=@OrderId"
      .Connection = sqlConn
   End With
   'Define and add the input parameter to the parameters collection
   param = sqlCmd.Parameters.Add(New _
                SqlParameter("@OrderId", SqlDbType.Int))
   'Specify the parameter direction
   param.Direction = ParameterDirection.Input
   'Set the parameter value
   param.Value = 1
   'Open the connection
   sqlConn.Open()
   'Execute the command and get a single value
   orderStatus = CInt(sqlCmd.ExecuteScalar())
Catch e As Exception
   ' Catch Exception here
Finally
   ' Close the connection
   sqlConn.Close()
End Try

注意 请参阅 BDAdotNetData2.vb 示例代码中的示例 1(本文开头提供了下载链接)。

使用Output 参数

带有 Output 参数的存储过程不仅可以有效地作为一种执行查询的方式,而且可以作为一种返回单行数据实体的方式。Output 参数是使用 ADO .NET “命令” 对象的参数集合来处理的。

在下面的示例中,存储过程的参数通过 “命令” 对象的 Parameters 集合来定义。该存储过程期待 Input 参数 "@OrderId" 和 Output 参数 "@OrderStatus",后者返回指定的定单的状态:

Dim sqlConn As SQLConnection
Dim sqlCmd As SQLCommand
Dim param As SQLParameter
Try
   ' Create a new connection object
   sqlConn = New SQLConnection(myConnString)
   ' Create a new command object
   sqlCmd = New SQLCommand()
   ' Specify the stored procedure and connection
   With sqlCmd
      .CommandType = CommandType.StoredProcedure
      .CommandText = "GetOrderStatus"
      . Connection = sqlConn
   End With
   ' Define and add the input parameter to the parameters collection
   param = SQLCmd.Parameters.Add(New _ SQLParameter("@OrderId", _
      SQLDBType.Int))
   With param
      ' Specify the parameter direction
      .Direction = ParameterDirection.Input
      ' Set the parameter value
      .Value = 1
   End with
   ' Define and add the output parameter to the parameters collection
   param = SQLCmd.Parameters.Add(New _
      SQLParameter("@OrderStatus", _
      SQLDBType.Int))
   ' Specify the parameter direction
   param.Direction = ParameterDirection.Output
   ' Open the connection
   SQLConn.Open()
   ' Execute the command
   sqlCmd. ExecuteNonQuery ()
   ' Do something with returned data
   orderStatus = sqlCmd.Parameters("@OrderStatus").Value.ToString
   ???…
Catch e As Exception
   ' Handle the exception
   ???…
Finally
   ' Close the connection
   sqlConn.Close()
End Try

注意 请参阅 BDAdotNetData2.vb 示例代码中的示例 2(本文开头提供了下载链接)。

使用 ADO .NET DataReader 对象

Output 参数有一个缺点,它需要数据库上相应的应用程序代码(例如,Microsoft SQL Server? 数据库的存储过程或 .mdb 数据库的参数查询)。ADO .NET DataReader 可以从即席 SQL 查询以及存储过程返回数据。DataReader 对象返回一个只进的只读数据流。

在下面的示例中,查询返回包含其 CustomerId 为 1 的客户发出的带有 OrderId 1 的定单的单个行。

Dim sqlConn As SQLConnection
Dim sqlCmd As SQLCommand
Dim sqlDataRdr As SqlDataReader
???…
Try
   ' Create a new connection object
   SqlConn = New SQLConnection(myConnString)
   ' Create a new command object
   SqlCmd = New SQLCommand()
   ' Specify the command to be exceuted
   With sqlCmd
      .CommandType = CommandType.Text
      .CommandText = "Exec GetOrderHeader @OrderId=1"
      .Connection = sqlConn
   End With
   ' Open the connection
   sqlConn.Open()
   ' Execute the command and retrieve the row in the DataReader
   sqlDataRdr = sqlCmd.ExecuteReader()
   ' Position the pointer at the row
   sqlDataRdr.Read()
   ' Do something with the row
   outString = sqlDataRdr.Item("OrderId").ToString() and "," and _
      sqlDataRdr.Item("CustomerId").ToString() and "," and _
      sqlDataRdr.Item("OrderStatus").ToString() and "," and _
      sqlDataRdr.Item("OrderDate").ToString()
Catch e As Exception
   ' Handle the exception
   ???…
Finally
   ' Close the DataReader
   sqlDataRdr.Close()
   ' Close the connection
   sqlConn.Close()
End Try

注意 请参阅 BDAdotNetData2.vb 示例代码中的示例 3(本文开头提供了下载链接)。

使用 ADO .NET SQLCommand 对象和 XmlReader

Microsoft SQL Server 2000 的设计支持 XML 能力。现在,通过使用 FOR XML 子句,“选择” 语句的结果能以 XML 形式返回。要直接从 SQL Server 2000 检索 XML 形式的结果,可以使用 SQLCommand 对象的 ExecuteXmlReader 方法。ExecuteXmlReader 返回包含从 SQL Server 2000 返回的 XML 的 System.Xml.XmlReader 对象。

在下面的示例中,SQLCommand 对象执行一个 SELECT 语句,该语句使用 FOR XML 子句返回 XML 形式的结果。

Dim sqlConn As SqlConnection
Dim sqlCmd As SqlCommand
Dim xmlRdr As XmlReader
Try
   ' Create a new connection object
   sqlConn = New SqlConnection(myConnString)
   ' Create a new command object
   sqlCmd = New SqlCommand()
   ' Specify the command to be exceuted
   With sqlCmd
      .CommandType = CommandType.Text
      ' Use FOR XML Clause to get results as XML
      .CommandText = _ 
"Select * from Orders where OrderId = 1 For XML Auto"
      .Connection = sqlConn
   End With
   ' Open the connection
   sqlConn.Open()
   ' Execute the command and retrieve the row in the DataReader
   xmlRdr = sqlCmd.ExecuteXmlReader()
   ' Move to the Root Element
   xmlRdr.MoveToContent()
   ' Do something with the data
   outXML = xmlRdr.ReadOuterXML()
   ???…
Catch e As Exception
   ' Catch Exception
Finally
   sqlConn.Close()
End Try

注意 请参阅 BDAdotNetData2.vb 示例代码中的示例 4(本文开头提供了下载链接)。

使用 ADO .NET DataSet 对象

“数据集” 对象是 Microsoft? .NET Framework 提供的主要脱机数据容器。它是一个复杂的缓存,与 SQL 和 ADO 托管提供程序共同支持从数据源读取数据以及将修改的数据写回数据源。尽管单行数据实体实际上只需要该缓存中很小一部分空间,但是,“数据集” 对象仍然是单行数据实体应该考虑的有用容器。

DataAdapter 对象充当数据源和 “数据集” 对象之间的映射层。它从数据源检索数据,填充 “数据集” 对象,然后将更改发送回数据源。

在下面的示例中,查询返回包含其 CustomerId 为 1 的客户发出的带有 OrderId 1 的定单的单个行。

Dim resultDS As DataSet
Dim sqlDA As SqlDataAdapter
Try
   '
   '
   ' Create a new DataAdapter object
   sqlDA = New SqlDataAdapter()
   ' Create a new DataSet
   resultDS = New DataSet()
   With sqlDA
      ' Add a SelectCommand object
      .SelectCommand = New SqlCommand()
      ' Specify the Select Command
      With .SelectCommand
         .CommandType = CommandType.Text
         .CommandText = "Exec GetOrderHeader @OrderId=1"
         .Connection = New SqlConnection(myConnString)
      End With
      ' Populate the DataSet with the returned data
      .Fill(resultDS, "Order")
   End With''""'""
' Do something with the row
colValue = _ 
      resultDS.Tables("Order").Rows(0).Item("ShipToName").ToString()
???…
Catch E As Exception
' Handle the exception
???…
Finally
'   ???…
End Try

注意 请参阅 BDAdotNetData2.vb 示例代码中的示例 5(本文开头提供了下载链接)。

写操作

利用 ADO .NET 对象,可以轻松地修改单个行并将其发送回数据源。最简单的写操作方法是,使用 “命令” 对象执行即席 SQL 或存储过程。“数据集” 命令提供了更多特性,尤其是在数据已检索到 “数据集” 对象的情况下。

使用 ADO .NET Command 对象

我们将在另一篇相关文章Data Operations That Do Not Return Rows中讨论使用 ADO .NET “命令” 对象执行即席 SQL 或存储过程。

使用 ADO .NET DataAdapter 对象

DataAdapter 对象用于连接到数据源、检索数据以及用数据填充 “数据集” 对象。可以更改 “数据集” 对象中的数据。DataAdapter 与数据源协调 “数据集” 对象中的更改。

使用 DataSet 对象

DataAdapter 对象的 “更新” 方法将 “数据集” 对象中缓存的更改提交到数据源。DataAdapter 对象使用 InsertCommand 提交新行,使用 UpdateCommand 提交修改的行,使用 DeleteCommand 从数据库删除行。

如果您指定 DataAdapter 对象的InsertCommandUpdateCommandDeleteCommand 属性,“更新” 方法将分别执行 “插入”“更新”“删除”。另一种可能更简单的方法是,使用 CommandBuilder 对象基于 SelectCommand 自动生成 Insert、Update 和 Delete 命令。最佳方法是,完全指定您自己的 InsertCommandDeleteCommandUpdateCommand,因为这样可以明确地控制如何进行更新,并且获得的性能要优于“自动生成”方法。

本文只讨论用于更新更改过的数据源的自动生成的命令。有关如何指定您自己的 “插入”“更新”“删除” 命令的信息,请参阅相关文章Data Operations on Sets of Rows

自动生成的 Insert 命令

DataAdapter 对象调用 “更新” 方法时,它将根据您指定的 “选择” 命令(如果尚未设定 InsertCommand 属性)自动生成 “插入” 命令。

在下面的代码示例中,用包含一个定单的单个行填充 “数据集” 对象。将一个新行添加到 “数据集” 对象,然后将该对象插入到数据源中的表中:

Dim sqlDA As SqlDataAdapter
Dim resultDS As DataSet
Dim workRow As DataRow
Dim sqlCmdBldr As SqlCommandBuilder
Try        
    '
   ' Create a new DataSet
   resultDS = New DataSet()
   ' Create a new DataAdapter object
   sqlDA = New SqlDataAdapter()
   ' Create the CommandBuilder object to automatically generate the 
   ' Insert, Update, and Delete Statements
   sqlCmdBldr = New SqlCommandBuilder(sqlDA)
   With sqlDA
      ' Add a SelectCommand object
      .SelectCommand = New SqlCommand()
      ' Specify the Select command
      With .SelectCommand
         .CommandType = CommandType.Text
         ' Query on non-existing row returns empty row with metadata
         .CommandText = "Exec GetOrderHeader @OrderId=-1"
         .Connection = New SqlConnection(myConnString)
      End With
      ' Populate the DataSet with the returned data
      .Fill(resultDS, "Order")
   End With'
' Set the default values for columns                
resultDS.Tables("Order"). _ 
Columns("ShippingHandling").DefaultValue = 0
    resultDS.Tables("Order").Columns("Tax").DefaultValue = 0
    resultDS.Tables("Order").Columns("SubTotal").DefaultValue = 0

   ' Create a new Row
   workRow = resultDS.Tables("Order").NewRow
   ' Fill in workrow data
   workRow.Item("CustomerId") = 1
   workRow.Item("OrderStatus") = 400
   workRow.Item("OrderDate") = Now()
   workRow.Item("ShipToName") = "ResidentBDAdotNetData2Example4"
   workRow.Item("ShipToAddressId") = 1
   ' Add the row to the DataSet
   resultDS.Tables("Order").Rows.Add(workRow)
   ' Reconcile changes with the data source
   sqlDA.Update(resultDS, "Order") 
Catch E As Exception
' Handle the exception
???…
Finally
   ' Close Connection and other cleanup code here
End Try

注意 请参阅 BDAdotNetData2.vb 示例代码中的示例 6(本文开头提供了下载链接)。

自动生成的 Update 命令

DataAdapter 对象调用 “更新” 方法时,它将根据您指定的 “选择” 命令(如果尚未设定 UpdateCommand 属性)自动生成 “更新” 命令。

在下面的代码示例中,用包含一个定单的单个行填充 “数据集” 对象。更新 “数据集” 对象中的行。最后,DataAdapter 对象将更改发送回数据源:

Dim sqlDA As SqlDataAdapter()
Dim resultDS As DataSet()
Dim sqlCmdBldr As SqlCommandBuilder
Dim colItemName As String
Try
   '
   ' Create a new DataSet
   resultDS = New DataSet()
    ' Create a new DataAdapter object
    sqlDA = New SqlDataAdapter()
   ' Create the CommandBuilder object
   sqlCmdBldr = New SqlCommandBuilder(sqlDA)
   With sqlDA
      ' Add a new SelectCommand object
      .SelectCommand = New SqlCommand()
      ' Specify the Select command
      With .SelectCommand
      .CommandType = CommandType.StoredProcedure
      ' Get last Order (as created by Example 4)
      .CommandText = "GetLastOrderHeader"
      .Connection = New SqlConnection(myConnString)
      End With
      ' Populate the DataSet with the returned data
      .Fill(resultDS, "Order")
   End With'
   ' Update the Row
   resultDS.Tables("Order").Rows(0).Item("ShipToName") = _ 
"Resident BDAdotNetData2Example5"
   ' Reconcile Changes
sqlDA.Update(resultDS, "Order")
Catch E As Exception
   ' Handle the exception
   ???…
Finally
End Try

注意 请参阅 BDAdotNetData2.vb 示例代码中的示例 7(本文开头提供了下载链接)。

自动生成的 Delete 命令

DataAdapter 对象调用 “更新” 方法时,它将根据您指定的 “选择” 命令(如果尚未设定 DeleteCommand 属性)自动生成 “删除” 命令。

在下面的代码示例中,用包含一个定单的单个行填充 “数据集” 对象。删除 “数据集” 对象中的行。最后,DataAdapter 对象更新数据库:

Dim sqlDA As SqlDataAdapter()
Dim resultDS As DataSet()
Dim sqlCmdBldr As SqlCommandBuilder
Dim workRow As DataRow
Dim colItemName As String
Try
   ' Create a new connection object
   sqlConn = New SqlConnection(myConnString)
   ' Create a new DataSet
   resultDS = New DataSet()
   ' Create a new DataAdapter object
    sqlDA = New SqlDataAdapter()
   ' Add a SelectCommand object
   sqlDA.SelectCommand = New SqlCommand()
   sqlCmdBldr = New SqlCommandBuilder(sqlDA)
   With sqlDA
      ' Add a SelectCommand object
      .SelectCommand = New SqlCommand()
      ' Specify the Select command
      With .SelectCommand
         .CommandType = CommandType.StoredProcedure
         ' Get last Order (as created by Example 4). Delete will fail if        
         ' this Order has details
         .CommandText = "GetLastOrderHeader"
         .Connection = New SqlConnection(myConnString)
                End With
                ' Populate the DataSet with the returned data
                .Fill(resultDS, "Order")
            End With'
   ' Delete the row from the Order table in the DataSet
   resultDS.Tables("Order").Rows(0).Delete()
   ' Reconcile changes with the data source
sqlDA.Update(resultDS, "Order")
Catch E As Exception
   ' Handle the exception
   ???…
Finally
   ' Cleanup code here
End Try

注意 请参阅 BDAdotNetData2.vb 示例代码中的示例 8(本文开头提供了下载链接)。

小结

ADO .NET 提供了各种有用的方法来读取和写入单行数据实体。为了选择最合适的方法,不仅要考虑对数据源执行的操作,而且应该考虑数据在应用程序内的表示形式。InputOutput 参数、DataReaderXMLReader 对象是轻量级的并可提供良好的性能,而 “数据集” 对象却可将有用的数据容器与高级特性结合起来。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值