DataAdapter 具有四项用于从数据源检索数据和向数据源更新数据的属性。SelectCommand 属性从数据源中返回数据。InsertCommandUpdateCommandDeleteCommand 属性用于管理数据源中的更改。在调用 DataAdapterFill 方法之前,必须设置 SelectCommand 属性。根据对 DataSet 中的数据作出的更改,在调用 DataAdapterUpdate 方法之前,必须设置 InsertCommandUpdateCommandDeleteCommand 属性。例如,如果已添加行,在调用 Update 之前必须设置 InsertCommand。当 Update 处理已插入、更新或删除的行时,DataAdapter 将使用相应的 Command 属性来处理该操作。有关已修改行的当前信息将通过 Parameters 集合传递到 Command 对象。

例如,当更新数据源中的行时,将调用 UPDATE 语句,它使用唯一标识符来表示该表中要更新的行。该唯一标识符通常是主键字段的值。UPDATE 语句使用既包含唯一标识符又包含要更新的列和值的参数,如以下 SQL 语句所示。

UPDATE Customers SET CompanyName = @CompanyName WHERE CustomerID = @CustomerID

在该示例中,CompanyName 字段使用其中 CustomerID 等于 @CustomerID 参数值的行的 @CompanyName 参数的值来进行更新。这些参数使用 Parameter 对象的 SourceColumn 属性从已修改的行中检索相关信息。下面是上一示例 UPDATE 语句的参数。

custDA.Parameters.Add("@CompanyName", SqlDbType.NChar, 15, "CompanyName")
Dim myParm As SqlParameter = custDA.UpdateCommand.Parameters.Add("@CustomerID", _
                                              SqlDbType.NChar, 5, "CustomerID")
myParm.SourceVersion = DataRowVersion.Original

Parameters 集合的 Add 方法采用参数的名称、DataAdapter 特定类型、大小(如果可应用于该类型)以及 DataTableSourceColumn 的名称。请注意,@CustomerID 参数的 SourceVersion 设置为 Original。这样,如果标识列的值已经在修改后的 DataRow 中被更改,就一定会更新数据源中的现有行。在这种情况下,Original 行值将匹配数据源中的当前值,而 Current 行值将包含更新的值。如果没有为 @CompanyName 参数设置 SourceVersion,而将使用默认的 Current 行值。

以下示例显示要用作 DataAdapterSelectCommandInsertCommandUpdateCommandDeleteCommand 属性的 CommandText 的示例 SQL 语句。对于 OleDbDataAdapter 对象,必须使用问号 (?) 占位符来标识参数。对于 SqlDataAdapter 对象,必须使用命名参数。

SqlClient

Dim selectSQL As String = "SELECT CustomerID, CompanyName FROM Customers WHERE Country = @Country AND City = @City"
Dim insertSQL As String = "INSERT INTO Customers (CustomerID, CompanyName) VALUES (@CustomerID, @CompanyName)"

Dim updateSQL As String = "UPDATE Customers SET CustomerID = @CustomerID, CompanyName = @CompanyName WHERE CustomerID = @OldCustomerID"

Dim deleteSQL As String = "DELETE FROM Customers WHERE CustomerID = @CustomerID"

string selectSQL = "SELECT CustomerID, CompanyName FROM Customers WHERE Country = @Country AND City = @City";
string insertSQL = "INSERT INTO Customers (CustomerID, CompanyName) VALUES (@CustomerID, @CompanyName)";

string updateSQL = "UPDATE Customers SET CustomerID = @CustomerID, CompanyName = @CompanyName WHERE CustomerID = @OldCustomerID";

string deleteSQL = "DELETE FROM Customers WHERE CustomerID = @CustomerID";

OleDb

Dim selectSQL As String = "SELECT CustomerID, CompanyName FROM Customers WHERE Country = ? AND City = ?"
Dim insertSQL AS String = "INSERT INTO Customers (CustomerID, CompanyName) VALUES (?, ?)"

Dim updateSQL AS String = "UPDATE Customers SET CustomerID = ?, CompanyName = ? WHERE CustomerID = ?"

Dim deleteSQL As String = "DELETE FROM Customers WHERE CustomerID = ?"

string selectSQL = "SELECT CustomerID, CompanyName FROM Customers WHERE Country = ? AND City = ?";
string insertSQL = "INSERT INTO Customers (CustomerID, CompanyName) VALUES (?, ?)";

string updateSQL = "UPDATE Customers SET CustomerID = ?, CompanyName = ? WHERE CustomerID = ? ";

string deleteSQL = "DELETE FROM Customers WHERE CustomerID = ?";

参数化查询语句定义将需要创建哪些输入和输出参数。若要创建参数,请使用 Parameters.Add 方法或 Parameter 构造函数来指定列名称、数据类型和大小。对于内部数据类型(如 Integer),无需包含大小或者可以指定默认大小。

以下代码示例为上一示例中的 SQL 语句创建参数并填充 DataSet

SqlClient

Dim nwindConn As SqlConnection = New SqlConnection("Data Source=localhost;Integrated Security=SSPI;Initial Catalog=northwind")
Dim custDA As SqlDataAdapter = New SqlDataAdapter

Dim selectCMD AS SqlCommand = New SqlCommand(selectSQL, nwindConn)
custDA.SelectCommand = selectCMD

' Add parameters and set values.
selectCMD.Parameters.Add("@Country", SqlDbType.NVarChar, 15).Value = "UK"
selectCMD.Parameters.Add("@City", SqlDbType.NVarChar, 15).Value = "London"

Dim custDS As DataSet = New DataSet
custDA.Fill(custDS, "Customers")

SqlConnection nwindConn = new SqlConnection("Data Source=localhost;Integrated Security=SSPI;Initial Catalog=northwind");
SqlDataAdapter custDA = new SqlDataAdapter();         

SqlCommand selectCMD = new SqlCommand(selectSQL, nwindConn);
custDA.SelectCommand = selectCMD;

// Add parameters and set values.
selectCMD.Parameters.Add("@Country", SqlDbType.NVarChar, 15).Value = "UK";
selectCMD.Parameters.Add("@City", SqlDbType.NVarChar, 15).Value = "London";

DataSet custDS = new DataSet();
custDA.Fill(custDS, "Customers");

OleDb

Dim nwindConn As OleDbConnection = New OleDbConnection("Provider=SQLOLEDB;Data Source=localhost;Integrated Security=SSPI;Initial Catalog=northwind")
Dim custDA As OleDbDataAdapter = New OleDbDataAdapter 

Dim selectCMD AS OleDbCommand = New OleDbCommand(selectSQL, nwindConn)
custDA.SelectCommand = selectCMD

' Add parameters and set values.
selectCMD.Parameters.Add("@Country", OleDbType.VarChar, 15).Value = "UK"
selectCMD.Parameters.Add("@City", OleDbType.VarChar, 15).Value = "London"

Dim custDS As DataSet = New DataSet
custDA.Fill(custDS, "Customers")

OleDbConnection nwindConn = new OleDbConnection("Provider=SQLOLEDB;Data Source=localhost;Integrated Security=SSPI;Initial Catalog=northwind;");
OleDbDataAdapter custDA = new OleDbDataAdapter();

OleDbCommand selectCMD = new OleDbCommand(selectSQL, nwindConn);
custDA.SelectCommand = selectCMD;

// Add parameters and set values.
selectCMD.Parameters.Add("@Country", OleDbType.VarChar, 15).Value = "UK";
selectCMD.Parameters.Add("@City", OleDbType.VarChar, 15).Value = "London";

DataSet custDS = new DataSet();
custDA.Fill(custDS, "Customers");

注意 如果没有为参数提供参数名称,则将给该参数提供递增的默认名称 ParameterN,参数名称从“Parameter1”开始。建议在提供参数名称时避免使用“ParameterN”命名约定,因为所提供的名称可能会与 ParameterCollection 中现有的默认参数名称发生冲突。如果提供的名称已经存在,将引发异常。

Parameter.DbType

参数的类型针对于 .NET 数据提供程序。如果指定类型,则会在向数据源传递值之前将 Parameter 的值转换为 .NET 数据提供程序类型。如果未指定类型,ADO.NET 将从 Parameter 对象的 Value 的 .NET 框架类型推断 Parameter 的 .NET 数据提供程序类型。

也可以通过将 Parameter 对象的 DbType 属性指定为特定的 System.Data.DbType,以一般的方式来指定 Parameter 的类型。此外,ADO.NET 将从 Parameter 对象的 DbType 推断 Parameter 的 .NET 数据提供程序类型。

Parameter 对象的 .NET 数据提供程序类型是从 Parameter 对象的 Value 的 .NET 框架类型或从 Parameter 对象的 DbType 来进行推断的,如下表所示。

.NET 框架类型 System.Data.DbType SqlDbType OleDbType
bool Boolean Bit Boolean
byte Byte TinyInt UnsignedTinyInt
byte[] Binary VarBinary。如果字节数组大于 VarBinary 的最大大小(8000 字节),此隐式转换将失败。对于大于 8000 字节的字节数组,请显式设置 SqlDbType VarBinary
char   不支持从 char 推断 SqlDbType Char
DateTime DateTime DateTime DBTimeStamp
Decimal Decimal Decimal Decimal
double Double Float Double
float Single Real Single
Guid Guid UniqueIdentifier Guid
int   Int Integer
Int16 Int16 SmallInt SmallInt
Int32 Int32 Int Int
Int64 Int64 BitInt BigInt
long   BigInt BigInt
object Object Variant Variant
short   SmallInt SmallInt
string string NVarChar。如果字符串大于 NVarChar 的最大大小(4000 字节),此隐式转换将失败。对于大于 4000 字符的字符串,请显式设置 SqlDbType VarWChar
UInt16 UInt16 不支持从 UInt16 推断 SqlDbType UnsignedSmallInt
UInt32 UInt32 不支持从 UInt32 推断 SqlDbType UnsignedInt
UInt64 UInt64 不支持从 UInt64 推断 SqlDbType UnsignedBigInt
  AnsiString VarChar VarChar
  Currency Money Currency
  Date DateTime DBDate
  SByte TinyInt TinyInt
  Time DateTime DBTime
  VarNumeric 不支持从 VarNumeric 推断 SqlDbType VarNumeric

Parameter.Direction

下表显示可以与 ParameterDirection 枚举一起用来设置 ParameterDirection 的值。

成员名称 说明
Input 该参数是输入参数。这是默认值。
InputOutput 该参数能够输入和输出。
Output 该参数是输出参数。
ReturnValue 该参数表示返回值。

以下代码示例显示如何设置 ParameterDirection

myParm.Direction = ParameterDirection.Output

Parameter.SourceColumn,Parameter.SourceVersion

SourceColumnSourceVersion 可以作为参数传递到 Parameter 构造函数,或设置为现有 Parameter 的属性。SourceColumn 是来自将在其中检索 Parameter 值的 DataRowDataColumn 的名称。SourceVersion 指定 DataAdapter 使用哪个 DataRow 版本来检索值。

下表显示可以与 SourceVersion 一起使用的 DataRowVersion 枚举值。

成员名称 说明
Current 该参数使用列的当前值。这是默认值。
Default 该参数使用列的 DefaultValue
Original 该参数使用列的初始值。
Proposed 该参数使用建议值。

以下代码示例定义一个 UPDATE 语句,在该语句中,CustomerID 列用作以下两个参数的 SourceColumn@CustomerID (SET CustomerID = @CustomerID) 和 @OldCustomerID (WHERE CustomerID = @OldCustomerID)。@CustomerID 参数用于将 CustomerID 列更新为 DataRow 中的当前值。因此,将使用 SourceVersionCurrentCustomerID SourceColumn@OldCustomerID 参数用于标识数据源中的当前行。由于在该行的 Original 版本中找到了匹配列值,所以将使用 SourceVersionOriginal 的相同 SourceColumn (CustomerID)。

SqlClient

custDA.UpdateCommand.Parameters.Add("@CustomerID", SqlDbType.NChar, 5, "CustomerID")

custDA.UpdateCommand.Parameters.Add("@CompanyName", SqlDbType.NVarChar, 40, "CompanyName")

Dim myParm As SqlParameter = custDA.UpdateCommand.Parameters.Add("@OldCustomerID",SqlDbType.NChar, 5, "CustomerID")
myParm.SourceVersion = DataRowVersion.Original

custDA.UpdateCommand.Parameters.Add("@CustomerID", SqlDbType.NChar, 5, "CustomerID");

custDA.UpdateCommand.Parameters.Add("@CompanyName", SqlDbType.NVarChar, 40, "CompanyName");

SqlParameter myParm = custDA.UpdateCommand.Parameters.Add("@OldCustomerID", SqlDbType.NChar, 5, "CustomerID");
myParm.SourceVersion = DataRowVersion.Original;

OleDb

custDA.UpdateCommand.Parameters.Add("@CustomerID", OleDbType.Char, 5,"CustomerID")

custDA.UpdateCommand.Parameters.Add("@CompanyName", OleDbType.VarChar, 40, "CompanyName")

Dim myParm As OleDbParameter = custDA.UpdateCommand.Parameters.Add("@OldCustomerID",OleDbType.Char, 5, "CustomerID")
myParm.SourceVersion = DataRowVersion.Original

custDA.UpdateCommand.Parameters.Add("@CustomerID", OleDbType.Char, 5, "CustomerID");

custDA.UpdateCommand.Parameters.Add("@CompanyName", OleDbType.VarChar, 40, "CompanyName");

OleDbParameter myParm = custDA.UpdateCommand.Parameters.Add("@OldCustomerID", OleDbType.Char, 5, "CustomerID");
myParm.SourceVersion = DataRowVersion.Original;

UpdatedRowSource

可以使用 Command 对象的 UpdatedRowSource 属性控制从数据源中返回的值如何映射回 DataSet。通过将 UpdatedRowSource 属性设置为 UpdateRowSource 枚举值之一,可以控制是忽略 DataAdapter 命令返回的参数还是将其应用于 DataSet 中已更改的行。还可以指定是否将返回的第一个行(如果存在)应用于 DataSet 中已更改的行。

下表描述 UpdateRowSource 枚举的不同值,并说明它们如何影响与 DataAdapter 一起使用的命令的行为。

UpdateRowSource 说明
Both 输出参数和返回的结果集的第一行都可以映射到 DataSet 中已更改的行。
FirstReturnedRecord 只有返回的结果集第一行中的数据才可以映射到 DataSet 中已更改的行。
None 将忽略任何输出参数或返回的结果集的行。
OutputParameters 只有输出参数才可以映射到 DataSet 中已更改的行。