使用 .NET 构建分布式应用程序
Priya Dhawan
Microsoft Developer Network
2002 年 2 月修订
摘要: 本文涵盖了使用 ADO .NET 返回单行实体的数据操作。(14 页打印页)
请下载 Bdadotnet.msi 或 Bdadotnet_beta2.msi。
本页内容
| 简介 | |
| 返回数据的操作 | |
| 使用 Output 参数获取单个值 | |
| 使用 ADO .NET DataReader 对象 | |
| 使用 ADO .NET SQLCommand 对象和 XmlReader | |
| 使用 ADO .NET DataSet 对象 | |
| 写操作 | |
| 使用 ADO .NET Command 对象 | |
| 使用 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 对象的InsertCommand、UpdateCommand 或 DeleteCommand 属性,“更新” 方法将分别执行 “插入”、“更新” 或 “删除”。另一种可能更简单的方法是,使用 CommandBuilder 对象基于 SelectCommand 自动生成 Insert、Update 和 Delete 命令。最佳方法是,完全指定您自己的 InsertCommand、DeleteCommand 或 UpdateCommand,因为这样可以明确地控制如何进行更新,并且获得的性能要优于“自动生成”方法。
本文只讨论用于更新更改过的数据源的自动生成的命令。有关如何指定您自己的 “插入”、“更新” 和 “删除” 命令的信息,请参阅相关文章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 提供了各种有用的方法来读取和写入单行数据实体。为了选择最合适的方法,不仅要考虑对数据源执行的操作,而且应该考虑数据在应用程序内的表示形式。Input 和 Output 参数、DataReader 和 XMLReader 对象是轻量级的并可提供良好的性能,而 “数据集” 对象却可将有用的数据容器与高级特性结合起来。
本文介绍了使用 ADO.NET 进行单行数据实体的操作,包括返回数据和写操作。返回数据可通过 Output 参数、DataReader 对象等实现;写操作可利用 Command 对象、DataAdapter 对象等。还提及了自动生成插入、更新和删除命令的方法,最后指出选择合适方法需考虑操作和数据表示形式。
2521

被折叠的 条评论
为什么被折叠?



