SqlDataAdapter
类是 .NET Framework 中 System.Data.SqlClient
命名空间的一部分,它专为与 Microsoft SQL Server 数据库交互而设计。(与数据源的交互是通过 DataAdapter 控制的。DataAdapter 是用于填充 DataSet 和更新数据源的桥梁。它可以将 DataSet 中的数据与底层数据源进行同步,使您能够从数据源中检索数据并将修改保存回数据源。)
SqlDataAdapter
类充当 DataSet
和 SQL Server 数据库之间的桥梁。它提供了一些方法,用于从 SQL Server 数据库填充 DataSet
,并将对 DataSet
的更改更新到数据库中。(由于 DataSet 是独立于数据源的,您可以在其中加载和操作数据,而不需要始终与数据源保持连接。这使得 DataSet 成为处理离线数据的理想选择,例如在断开网络连接时或需要对数据进行离线处理时。)
以下是 SqlDataAdapter
类的一些主要特点和功能:
-
数据检索:
SqlDataAdapter
的Fill
方法用于从 SQL Server 数据库中检索数据并将其填充到DataSet
中。它执行针对数据库的 SQL 查询,并获取结果集,然后将结果集存储在DataSet
中。 -
数据更新:
SqlDataAdapter
的Update
方法用于将对DataSet
所做的更改发送回 SQL Server 数据库。它根据DataSet
中的更改自动生成并执行所需的 SQL 语句(插入、更新、删除)。 -
命令生成:
SqlDataAdapter
可以根据DataSet
的架构和数据更改自动生成所需的 SQL 语句(SELECT、INSERT、UPDATE、DELETE)。另外,您还可以使用SelectCommand
、InsertCommand
、UpdateCommand
和DeleteCommand
属性显式指定 SQL 命令。 -
连接管理:
SqlDataAdapter
可以在内部管理数据库连接,也可以使用现有的SqlConnection
对象。它会在数据检索和更新过程中根据需要打开和关闭连接。 -
数据映射:
SqlDataAdapter
使用DataTableMapping
类将结果集列映射到DataSet
中的DataTable
列。这样可以灵活地映射列名和类型。 -
参数化查询:
SqlDataAdapter
支持参数化查询,您可以为查询和命令添加参数,以处理安全性和数据完整性方面的考虑。
通过使用 SqlDataAdapter
类,您可以轻松地从 SQL Server 数据库中检索和更新数据,在 .NET 应用程序中提供了方便的与数据库交互的方式,并使用 DataSet
以离线方式处理数据。
以下是一个使用 SqlDataAdapter
的具体示例,展示了如何从 SQL Server 数据库中检索数据并将更改保存回数据库。
using System;
using System.Data;
using System.Data.SqlClient;
class Program
{
static void Main()
{
string connectionString = "Data Source=localhost;Initial Catalog=xxxtsl;User ID=sa;Password=xlqx8x0x11";
string query = "SELECT CustomerId, CustomerName, Email FROM tsl.dbo.Employees";
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlDataAdapter adapter = new SqlDataAdapter(query, connection);
adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey;
DataSet dataSet = new DataSet();
adapter.Fill(dataSet, "Employees");
DataTable employeesTable = dataSet.Tables["Employees"];
// 显示当前数据
Console.WriteLine("当前数据:");
DisplayData(employeesTable);
// 创建两行数据
DataRow newRow1 = employeesTable.NewRow();
newRow1["CustomerId"] = "00004";
newRow1["CustomerName"] = "John Doex";
newRow1["Email"] = "john@example.com";
employeesTable.Rows.Add(newRow1);
DataRow newRow2 = employeesTable.NewRow();
newRow2["CustomerId"] = "00005";
newRow2["CustomerName"] = "Jane Smithx";
newRow2["Email"] = "jane@example.com";
employeesTable.Rows.Add(newRow2);
// 设置插入命令
SqlCommand insertCommand = new SqlCommand("INSERT INTO tsl.dbo.Employees (CustomerId, CustomerName, Email) VALUES (@CustomerId, @CustomerName, @Email)", connection);
insertCommand.Parameters.Add("@CustomerId", SqlDbType.Char, 5, "CustomerId");
insertCommand.Parameters.Add("@CustomerName", SqlDbType.VarChar, 40, "CustomerName");
insertCommand.Parameters.Add("@Email", SqlDbType.VarChar, 100, "Email");
adapter.InsertCommand = insertCommand;
// 设置 UpdatedRowSource 属性为 UpdateRowSource.OutputParameters
adapter.InsertCommand.UpdatedRowSource = UpdateRowSource.OutputParameters;
// 进行批量插入
adapter.UpdateBatchSize = 2;
adapter.Update(dataSet, "Employees");
Console.WriteLine("数据批量插入完成。");
// 再次显示当前数据
Console.WriteLine("再次显示当前数据:");
DisplayData(employeesTable);
// 获取要修改的 CustomerId
string targetCustomerId = "28910";
// 修改数据
Console.WriteLine("修改数据...");
foreach (DataRow row in employeesTable.Rows)
{
if (row["CustomerId"].ToString() == targetCustomerId)
{
row["CustomerName"] = "gemzhxxx";
row["Email"] = "gemzhxx@example.com";
}
}
// 保存更新后的数据
SqlDataAdapter updateAdapter = new SqlDataAdapter();
updateAdapter.UpdateCommand = new SqlCommand("UPDATE tsl.dbo.Employees SET CustomerName = @CustomerName, Email = @Email WHERE CustomerId = @CustomerId", connection);
updateAdapter.UpdateCommand.Parameters.Add("@CustomerName", SqlDbType.VarChar, 40, "CustomerName");
updateAdapter.UpdateCommand.Parameters.Add("@Email", SqlDbType.VarChar, 100, "Email");
updateAdapter.UpdateCommand.Parameters.Add("@CustomerId", SqlDbType.Char, 5, "CustomerId");
updateAdapter.Update(dataSet, "Employees");
Console.WriteLine("数据更新完成。");
// 显示更新后的数据
Console.WriteLine("更新后的数据:");
DisplayData(employeesTable);
Console.ReadLine();
}
}
static void DisplayData(DataTable dataTable)
{
Console.WriteLine("{0,-12}{1,-15}{2,-15}", "CustomerId", "CustomerName", "Email");
foreach (DataRow row in dataTable.Rows)
{
Console.Write("{0,-12}", row["CustomerId"]);
Console.Write("{0,-15}", row["CustomerName"]);
Console.Write("{0,-15}", row["Email"]);
Console.WriteLine();
}
}
}
SqlDataAdapter
还提供了其他功能,可以进一步增强数据操作的能力。以下是一些 SqlDataAdapter
的附加功能:
-
批量操作:
SqlDataAdapter
支持批量操作,可以一次性插入、更新或删除多行数据。通过设置UpdateBatchSize
属性,您可以指定要一次性发送到数据库的行数。 -
数据筛选和排序:
SqlDataAdapter
允许您使用RowFilter
属性对填充到DataSet
或DataTable
中的数据进行筛选。您可以使用类似 SQL 的表达式来指定筛选条件。此外,您还可以使用Sort
属性对数据进行排序。 -
事务处理:
SqlDataAdapter
可以与事务一起使用,确保一系列数据库操作的原子性和一致性。您可以在SqlDataAdapter
上使用BeginTransaction
方法启动事务,并使用Commit
或Rollback
方法提交或回滚事务。 -
数据校验和约束:通过使用
DataSet
的DataTable
对象的约束,例如主键约束、外键约束和唯一约束,以及在数据库中定义的约束,SqlDataAdapter
可以自动进行数据校验和约束验证。 -
参数缓存:
SqlDataAdapter
在执行参数化查询时会缓存生成的参数化命令,以提高性能。这可以减少重复查询时的命令解析和参数生成的开销。
以下是一个完整的示例程序,演示了 SqlDataAdapter
的批量操作、数据筛选和排序、事务处理以及数据校验和约束的功能。
using System;
using System.Data;
using System.Data.SqlClient;
namespace SqlDataAdapterExample
{
class Program
{
static void Main(string[] args)
{
// 连接字符串
string connectionString = "Data Source=(local);Initial Catalog=SampleDB;Integrated Security=True";
// 创建一个 DataSet 用于存储数据
DataSet dataSet = new DataSet();
// 创建一个 SqlDataAdapter 对象
using (SqlDataAdapter adapter = new SqlDataAdapter())
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
// 设置查询语句
string query = "SELECT * FROM Employees";
// 设置连接和查询
adapter.SelectCommand = new SqlCommand(query, connection);
// 打开数据库连接
connection.Open();
// 从数据库填充数据到 DataSet
adapter.Fill(dataSet, "Employees");
// 关闭数据库连接
connection.Close();
}
}
// 批量插入数据
DataTable employeesTable = dataSet.Tables["Employees"];
// 创建新行并添加到 DataTable
DataRow newRow1 = employeesTable.NewRow();
newRow1["Name"] = "Jane Doe";
newRow1["Age"] = 28;
employeesTable.Rows.Add(newRow1);
DataRow newRow2 = employeesTable.NewRow();
newRow2["Name"] = "Bob Smith";
newRow2["Age"] = 35;
employeesTable.Rows.Add(newRow2);
// 执行批量插入
using (SqlDataAdapter adapter = new SqlDataAdapter())
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
// 设置插入命令
adapter.InsertCommand = new SqlCommand("INSERT INTO Employees (Name, Age) VALUES (@Name, @Age)", connection);
adapter.InsertCommand.Parameters.Add("@Name", SqlDbType.NVarChar, 50, "Name");
adapter.InsertCommand.Parameters.Add("@Age", SqlDbType.Int, 0, "Age");
// 打开数据库连接
connection.Open();
// 启动事务
SqlTransaction transaction = connection.BeginTransaction();
adapter.InsertCommand.Transaction = transaction;
try
{
// 批量插入数据
adapter.UpdateBatchSize = 2;
adapter.Update(dataSet, "Employees");
// 提交事务
transaction.Commit();
Console.WriteLine("批量插入数据成功!");
}
catch (Exception ex)
{
// 回滚事务
transaction.Rollback();
Console.WriteLine("批量插入数据失败:{0}", ex.Message);
}
finally
{
// 关闭数据库连接
connection.Close();
}
}
}
// 数据筛选和排序
DataView dataView = new DataView(employeesTable);
dataView.RowFilter = "Age > 30"; // 筛选年龄大于30的员工
dataView.Sort = "Age DESC"; // 按年龄降序排序
Console.WriteLine("筛选和排序结果:");
foreach (DataRowView rowView in dataView)
{
Console.WriteLine("EmployeeID: {0}, Name: {1}, Age: {2}",
rowView["EmployeeID"], rowView["Name"], rowView["Age"]);
}
// 数据校验和约束
employeesTable.Constraints.Add(new UniqueConstraint("PK_Employees", employeesTable.Columns["EmployeeID"], true));
// 尝试插入重复的行
DataRow duplicateRow = employeesTable.NewRow();
duplicateRow["EmployeeID"] = 1;
duplicateRow["Name"] = "John Doe";
duplicateRow["Age"] = 30;
try
{
employeesTable.Rows.Add(duplicateRow);
Console.WriteLine("重复行插入成功!");
}
catch (Exception ex)
{
Console.WriteLine("重复行插入失败:{0}", ex.Message);
}
Console.ReadLine();
}
}
}
System.Data.SqlClient
类
是.NET Framework中的一个命名空间,提供与 Microsoft SQL Server 数据库进行交互的功能。它包含一些类和类型,用于在.NET应用程序中进行与 SQL Server 数据库的连接、查询、命令执行等操作。
以下是 System.Data.SqlClient
命名空间中的一些重要类:
-
SqlConnection
:用于建立与 SQL Server 数据库的连接,并提供了一些属性和方法来管理连接的状态、打开和关闭连接等。 -
SqlCommand
:用于执行 SQL 语句或存储过程,并提供了一些属性和方法来设置和执行命令,以及检索执行结果。 -
SqlDataReader
:用于从数据库中读取结果集的只进流,它提供了一些方法来逐行读取数据,并可以通过索引或列名访问数据。 -
SqlDataAdapter
:用于填充DataSet
或DataTable
对象,并提供了一些方法和属性来检索和更新数据。 -
SqlParameter
:用于表示 SQL 命令中的参数,并提供了一些属性和方法来设置参数的名称、类型、值等。 -
SqlTransaction
:用于在事务中执行一系列的数据库操作,并提供了一些方法来提交或回滚事务。
上述类提供了与 SQL Server 数据库进行连接、查询和数据操作的核心功能。通过使用这些类,您可以在.NET应用程序中与 SQL Server 数据库进行交互,执行 SQL 命令、读取数据、更新数据等操作。
请注意,System.Data.SqlClient
命名空间中的类是特定于 Microsoft SQL Server 的,如果要与其他类型的数据库进行交互,可能需要使用不同的命名空间和类库。
-----------------------------------
- ADO.NET DataSet
是一种内存中的数据表示形式,它提供了一种与数据源无关的编程模型,使您能够以一致的方式处理数据,而不管数据来自哪个数据源。
DataSet 包含了多个 DataTable 对象,每个 DataTable 表示一个数据表,其中包含行和列。您可以在 DataSet 中创建多个表,并使用关系将这些表连接在一起。这样,您可以模拟复杂的关系数据库结构。
DataSet 还支持约束,您可以定义表的约束,如主键、唯一约束、外键等。这些约束可以保证数据的完整性和一致性。
由于 DataSet 是独立于数据源的,您可以在其中加载和操作数据,而不需要始终与数据源保持连接。这使得 DataSet 成为处理离线数据的理想选择,例如在断开网络连接时或需要对数据进行离线处理时。
与数据源的交互是通过 DataAdapter 控制的。DataAdapter 是用于填充 DataSet 和更新数据源的桥梁。它可以将 DataSet 中的数据与底层数据源进行同步,使您能够从数据源中检索数据并将修改保存回数据源。
总之,ADO.NET DataSet 提供了一种强大的数据操作和管理工具,使您能够以一致的方式处理和操作来自不同数据源的数据,并且可以在断开连接的情况下对数据进行处理和修改。