C# 中 DataSet 类详解:内存缓存、XML 处理与 SQLite 应用示例
DataSet 是 C# ADO.NET 中的离线数据容器,可充当内存中的关系数据库,支持多表关联与 XML 交互。通过 SQLiteDataAdapter.Fill() 读取数据后,利用 Clone()/Copy() 处理架构或内容,并结合 Clear/Merge 等操作,可实现高效的本地数据管理。
结果或目标:理解 DataSet 的离线特性
DataSet 表示数据的内存中缓存。其核心价值在于断开式连接(Disconnection),即数据从数据库检索后,DataSet 便与数据源断开连接,在内存中进行后续处理。它不仅能容纳多个 DataTable,还能定义表间关系、约束,并支持与 XML 文档协同操作。这种机制非常适合需要在内存中暂存、修改和批量更新数据的应用场景。
准备条件:环境依赖
- C# 开发环境(.NET Framework 或 .NET Core / .NET 5+)。
- 若需操作 SQLite 数据库,建议引入
System.Data.SQLite库。 - 基础 ADO.NET 编程知识。
真实操作顺序:关键属性与方法梳理
第1步:掌握核心属性配置
DataSet 提供了丰富的属性用于控制其行为:
Tables:DataTableCollection,获取包含在数据集内的所有表格集合。Relations:获取用于将表链接起来的关系集合。EnforceConstraints:指示是否在尝试执行任何更新操作时遵循约束规则。CaseSensitive:指示 DataTable 对象中的字符串比较是否区分大小写。HasErrors:指示在此 DataSet 中的任何 DataTable 对象中是否存在错误。
第2步:执行数据变更与状态管理
对数据进行增删改后,需要通过方法提交或回滚:
AcceptChanges():提交自加载或上次调用以来对所有行的更改。此后HasChanges将返回 false。RejectChanges():回滚自创建 DataSet 以来或上次调用 AcceptChanges() 以来的所有更改。GetChanges(DataRowState):获取包含所有更改的子集副本,便于选择性回传。
第3步:处理数据集的结构与数据复制
根据需求选择复制或克隆:
Clone():仅复制结构(Schema),包括表头、关系和约束,不包含数据。Copy():同时复制结构和所有行数据。Merge():将指定DataTable、DataRow[]或另一个DataSet合并到当前集中,可指定冲突处理策略。
第4步:清空与重置操作
Clear():清除所有表中的所有行(只清数据,保留 Schema)。Reset():彻底清除所有表,并从DataSet中删除所有关系、外部约束和表,还原为初始空状态。
第5步:XML 序列化和反序列化
DataSet 原生支持 XML 格式转换:
ReadXml()/WriteXml():直接读写 XML 文件或流。ReadXmlSchema()/WriteXmlSchema():仅处理 XML Schema (XSD)。InferXmlSchema():从指定的 XML 内容推断结构并应用于 DataSet。
完成判断:界面与效果预期
在实际的 Windows Forms 或 WPF 应用中,操作完成后可观察到界面上 Grid 控件(如 DataGridView)显示的内容随逻辑改变。例如,使用 Clone 时表格为空但列名存在;使用 Clear 后行消失但结构仍在。
原文有依据的排错:常见误区
- 误用 Clear() 与 Reset():若希望恢复表结构以便重新填充,请勿使用
Reset(),因为它会销毁所有表定义。 - 路径硬编码:示例代码中使用了 SQLite 绝对路径(如
C:\Users\...\IC00.db)。在部署时应替换为相对路径或配置文件路径,避免跨机器报错。 - 类型混淆:注意代码中使用
SQLiteDataAdapter而非标准 SQL Server 的SqlDataAdapter,这取决于底层数据库类型。
简要总结:完整实战代码
以下是一个基于 SQLite 的 DataSet 使用流程。主要逻辑包括:建立连接 -> Fill 填充 DataSet -> 分别进行 Clone/Clear/Reset 测试 -> 绑定到 UI。
using System;
using System.Data;
using System.Data.SQLite;
using System.Windows.Forms;
namespace SQlite
{
public partial class Form1 : Form
{
// 必须使用绝对路径,可根据实际情况调整为相对路径
string connectionString = "data source=" + @"C:\Users\ASUS\Desktop\IC00\IC00.db";
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string sql = "select * from IC";
DataSet data = Select(sql); // 调用查询函数
// 选项1:复制数据(结构和数据全部拷贝)
DataSet dataSetCopy = data.Copy();
// 选项2:仅复制结构(无数据)
// DataSet dataSetClone = data.Clone();
// 选项3:数据清理 (只清空数据,不破坏结构)
// dataSetCopy.Clear();
// 选项4:重置 (清空数据和结构)
// dataSetCopy.Reset();
// 将数据源绑定至 GridView,Tables[0] 代表第一张表
dataGridView1.DataSource = data.Tables[0];
dataGridView2.DataSource = dataSetCopy.Tables[0];
}
// 自定义辅助方法,用于执行 SQL 并返回 DataSet
public DataSet Select(string SQL)
{
using (SQLiteConnection conn = new SQLiteConnection(connectionString))
{
DataSet ds = new DataSet();
try
{
conn.Open();
// 使用 DataAdapter 将数据“填充”入 DataSet
SQLiteDataAdapter com = new SQLiteDataAdapter(SQL, conn);
com.Fill(ds, "ds"); // 所有数据被封装为一个名为 "ds" 的 Table
}
catch (System.Data.SQLite.SQLiteException ex)
{
throw new Exception(ex.Message);
}
return ds;
}
}
}
}
综上所述,通过合理使用 DataSet 的属性与离线操作功能,可以大幅降低高频查询带来的服务器压力。以上就是 C# 中 DataSet 类使用技巧与 SQLite 操作的详细内容,更多关于 C# 数据处理与 ADO.NET 优化的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













