龙方德 發表於 2026-1-4 09:42:23

c#中DataSet类的具体使用

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li>一、DataSet 的核心特性</li><li>二、DataSet 的基本结构</li><li>三、DataSet 的常用方法与属性</li><li>四、使用示例:完整操作流程</li><ul class="second_class_ul"><li>1. 创建 DataSet 并定义表结构</li><li>2. 填充数据与操作行</li><li>3. 定义表关系与数据导航</li><li>4. 数据持久化(XML 导入 / 导出)</li><li>5. 与数据库同步(结合 DataAdapter)</li></ul><li>五、DataSet 的适用场景与局限性</li><ul class="second_class_ul"><li>适用场景:</li><li>局限性:</li></ul><li>六、总结</li><ul class="second_class_ul"></ul></ul></div><p>在 C# 的ADO.NET体系中,<code>DataSet</code>是一个<strong>内存中的数据容器</strong>,可视为 &ldquo;离线数据库&rdquo;,用于存储和管理关系型数据(包含表、表关系、约束等),且独立于底层数据源(如 SQL Server、MySQL 等)。它是处理复杂数据关系、离线数据操作的核心组件。</p>
<p class="maodian"></p><h2>一、DataSet 的核心特性</h2>
<ul><li><strong>离线数据存储</strong>:数据加载后与数据源断开连接,仍可在内存中操作,适合客户端离线场景。</li><li><strong>关系型结构</strong>:可包含多个<code>DataTable</code>(数据表),表之间通过<code>DataRelation</code>(关系)关联,支持主外键逻辑。</li><li><strong>数据状态跟踪</strong>:自动记录数据行的修改状态(新增、修改、删除),便于批量同步回数据源。</li><li><strong>架构独立性</strong>:自带数据架构(<code>Schema</code>),记录字段类型、约束(主键、唯一键等),不依赖数据源元数据。</li></ul>
<p class="maodian"></p><h2>二、DataSet 的基本结构</h2>
<p><code>DataSet</code>的结构类似小型数据库,核心组成如下:</p>
<ul><li>Tables集合:存储多个DataTable对象(数据表),每个DataTable对应一组结构化数据。</li><li>Relations集合:存储DataRelation对象,定义DataTable之间的关联关系(如 &ldquo;客户 - 订单&rdquo; 的一对多关系)。</li><li>ExtendedProperties:存储自定义键值对信息(如数据集描述、创建时间等)。</li></ul>
<p class="maodian"></p><h2>三、DataSet 的常用方法与属性</h2>
<table><thead><tr><th>方法 / 属性</th><th>说明</th></tr></thead><tbody><tr><td>Tables</td><td>获取DataTableCollection,用于访问或管理包含的DataTable</td></tr><tr><td>Relations</td><td>获取DataRelationCollection,用于管理表之间的关系</td></tr><tr><td>DataSetName</td><td>获取或设置数据集名称</td></tr><tr><td>AcceptChanges()</td><td>提交所有数据修改(将RowState重置为Unchanged)</td></tr><tr><td>RejectChanges()</td><td>撤销所有未提交的修改(恢复到上次AcceptChanges后的状态)</td></tr><tr><td>Merge(DataSet)</td><td>将另一个DataSet的数据合并到当前数据集(常用于合并离线修改)</td></tr><tr><td>Clear()</td><td>清空所有表中的数据(保留表结构)</td></tr><tr><td>GetXml()</td><td>将数据集内容转换为 XML 字符串</td></tr><tr><td>ReadXml(string)</td><td>从 XML 文件加载数据到数据集</td></tr></tbody></table>
<p class="maodian"></p><h2>四、使用示例:完整操作流程</h2>
<p>以下通过 &ldquo;客户 - 订单&rdquo; 数据模型,展示<code>DataSet</code>的创建、数据操作、关系管理和持久化的完整流程。</p>
<p class="maodian"></p><h3>1. 创建 DataSet 并定义表结构</h3>
<div class="jb51code"><pre class="brush:csharp;">// 1. 创建DataSet
DataSet salesDataSet = new DataSet("SalesData"); // 数据集名称

// 2. 创建客户表(Customers)
DataTable customerTable = new DataTable("Customers");
// 定义列(含主键)
customerTable.Columns.Add("CustomerId", typeof(int)); // 主键列
customerTable.Columns.Add("Name", typeof(string));
customerTable.Columns.Add("Phone", typeof(string));
// 设置主键
customerTable.PrimaryKey = new[] { customerTable.Columns["CustomerId"] };

// 3. 创建订单表(Orders)
DataTable orderTable = new DataTable("Orders");
orderTable.Columns.Add("OrderId", typeof(int)); // 主键列
orderTable.Columns.Add("CustomerId", typeof(int)); // 外键(关联Customers)
orderTable.Columns.Add("Amount", typeof(decimal));
orderTable.Columns.Add("OrderDate", typeof(DateTime));
orderTable.PrimaryKey = new[] { orderTable.Columns["OrderId"] };

// 4. 将表添加到DataSet
salesDataSet.Tables.Add(customerTable);
salesDataSet.Tables.Add(orderTable);

// 验证结构
Console.WriteLine($"数据集名称:{salesDataSet.DataSetName}");
Console.WriteLine($"包含表数量:{salesDataSet.Tables.Count}"); // 输出:2</pre></div>
<p class="maodian"></p><h3>2. 填充数据与操作行</h3>
<div class="jb51code"><pre class="brush:csharp;">// 1. 向客户表添加数据
DataTable customers = salesDataSet.Tables["Customers"];
customers.Rows.Add(1, "张三", "13800138000"); // 直接传值(按列顺序)
customers.Rows.Add(2, "李四", "13900139000");

// 2. 向订单表添加数据
DataTable orders = salesDataSet.Tables["Orders"];
orders.Rows.Add(1001, 1, 999.99m, new DateTime(2024, 1, 15)); // 张三的订单
orders.Rows.Add(1002, 1, 1599.50m, new DateTime(2024, 3, 20)); // 张三的订单
orders.Rows.Add(1003, 2, 599.00m, new DateTime(2024, 5, 10)); // 李四的订单

// 3. 修改数据
DataRow zhangsanRow = customers.Rows.Find(1); // 通过主键查找
zhangsanRow["Phone"] = "13812345678"; // 修改手机号

// 4. 删除数据
DataRow orderToDelete = orders.Rows.Find(1003); // 查找订单1003
if (orderToDelete != null)
    orderToDelete.Delete(); // 标记删除(未真正删除,需AcceptChanges确认)

// 5. 查看行状态(跟踪修改)
foreach (DataRow row in customers.Rows)
{
    Console.WriteLine($"客户ID: {row["CustomerId"]}, 状态: {row.RowState}");
}
// 输出:
// 客户ID: 1, 状态: Modified(已修改)
// 客户ID: 2, 状态: Unchanged(未修改)</pre></div>
<p class="maodian"></p><h3>3. 定义表关系与数据导航</h3>
<p>通过<code>DataRelation</code>建立表之间的关联,实现父子数据的快速导航。</p>
<div class="jb51code"><pre class="brush:csharp;">// 1. 创建“客户-订单”关系(一对多)
DataRelation customerOrderRel = new DataRelation(
    "FK_Customer_Order", // 关系名称
    salesDataSet.Tables["Customers"].Columns["CustomerId"], // 父表主键
    salesDataSet.Tables["Orders"].Columns["CustomerId"] // 子表外键
);
// 添加关系到DataSet
salesDataSet.Relations.Add(customerOrderRel);

// 2. 通过父行查找子行(查询张三的所有订单)
DataRow zhangsan = customers.Rows.Find(1);
if (zhangsan != null)
{
    // 获取张三的所有订单(子行)
    DataRow[] zhangsanOrders = zhangsan.GetChildRows(customerOrderRel);
    Console.WriteLine($"客户 {zhangsan["Name"]} 的订单数量:{zhangsanOrders.Length}");
   
    foreach (DataRow order in zhangsanOrders)
    {
      Console.WriteLine($"订单ID:{order["OrderId"]},金额:{order["Amount"]}");
    }
}

// 3. 通过子行查找父行(查询订单1001的客户)
DataRow order1001 = orders.Rows.Find(1001);
if (order1001 != null)
{
    DataRow customer = order1001.GetParentRow(customerOrderRel);
    Console.WriteLine($"订单1001的客户:{customer["Name"]}"); // 输出:张三
}</pre></div>
<p class="maodian"></p><h3>4. 数据持久化(XML 导入 / 导出)</h3>
<p><code>DataSet</code>支持直接与 XML 互转,方便数据持久化或传输。</p>
<div class="jb51code"><pre class="brush:csharp;">// 1. 将数据导出为XML(含结构和数据)
string xmlData = salesDataSet.GetXml();
Console.WriteLine("XML数据:");
Console.WriteLine(xmlData);

// 2. 保存到XML文件
salesDataSet.WriteXml("SalesData.xml"); // 仅数据
salesDataSet.WriteXmlSchema("SalesDataSchema.xml"); // 仅结构(Schema)

// 3. 从XML文件加载数据
DataSet newDataSet = new DataSet();
newDataSet.ReadXml("SalesData.xml");
newDataSet.ReadXmlSchema("SalesDataSchema.xml"); // 加载结构确保类型正确
Console.WriteLine($"从XML加载的客户表行数:{newDataSet.Tables["Customers"].Rows.Count}");</pre></div>
<p class="maodian"></p><h3>5. 与数据库同步(结合 DataAdapter)</h3>
<p><code>DataSet</code>的修改可通过<code>DataAdapter</code>批量更新回数据源,利用其状态跟踪功能自动生成增删改命令。</p>
<div class="jb51code"><pre class="brush:csharp;">string connectionString = "Server=.;Database=SalesDB;Integrated Security=True;";

// 1. 创建DataAdapter(作为DataSet与数据库的桥梁)
using (SqlDataAdapter adapter = new SqlDataAdapter())
{
    // 设置查询命令(用于从数据库加载数据)
    adapter.SelectCommand = new SqlCommand(
      "SELECT CustomerId, Name, Phone FROM Customers",
      new SqlConnection(connectionString)
    );

    // 自动生成增删改命令(需引用System.Data.SqlClient)
    SqlCommandBuilder cmdBuilder = new SqlCommandBuilder(adapter);

    // 2. 从数据库填充DataSet
    DataSet dbDataSet = new DataSet();
    adapter.Fill(dbDataSet, "Customers"); // 填充到"Customers"表

    // 3. 在内存中修改数据(模拟用户操作)
    DataTable dbCustomers = dbDataSet.Tables["Customers"];
    dbCustomers.Rows["Phone"] = "13888888888"; // 修改
    dbCustomers.Rows.Add(3, "王五", "13700137000"); // 新增
    dbCustomers.Rows.Delete(); // 删除

    // 4. 将修改同步回数据库(根据RowState自动执行对应SQL)
    int updatedRows = adapter.Update(dbDataSet, "Customers");
    Console.WriteLine($"成功同步 {updatedRows} 条修改到数据库");
}</pre></div>
<p class="maodian"></p><h2>五、DataSet 的适用场景与局限性</h2>
<p class="maodian"></p><h3>适用场景:</h3>
<ul><li><strong>离线数据处理</strong>:客户端需在无网络环境下操作数据(如移动应用)。</li><li><strong>复杂数据关系</strong>:需维护多表关联(如订单 - 订单明细 - 客户),并频繁导航数据。</li><li><strong>批量数据更新</strong>:需一次性提交多条增删改操作,减少数据库交互次数。</li><li><strong>数据缓存</strong>:重复使用的数据集可缓存到内存,提升性能。</li></ul>
<p class="maodian"></p><h3>局限性:</h3>
<ul><li><strong>内存占用高</strong>:数据全部加载到内存,不适合处理百万级以上大数据。</li><li><strong>数据一致性风险</strong>:离线操作可能导致与数据源数据冲突(需额外处理并发)。</li><li><strong>性能开销</strong>:相比<code>DataReader</code>(流式读取),初始化和序列化<code>DataSet</code>的开销更大。</li></ul>
<p class="maodian"></p><h2>六、总结</h2>
<p><code>DataSet</code>是 C# 中处理关系型数据的强大工具,其核心价值在于<strong>离线数据管理</strong>和<strong>复杂关系维护</strong>。通过与<code>DataTable</code>、<code>DataRelation</code>、<code>DataAdapter</code>等类配合,可构建完整的内存数据模型,灵活支持从数据加载、修改到同步的全流程。在实际开发中,需根据数据量和业务场景选择使用(小批量、多关系数据优先,超大数据量建议用<code>DataReader</code>)。</p>
<p>到此这篇关于c#中DataSet类的具体使用的文章就介绍到这了,更多相关c# DataSet类内容请搜索琼殿技术社区以前的文章或继续浏览下面的相关文章希望大家以后多多支持琼殿技术社区!</p>
                           
                            <div class="art_xg">
                              <b>您可能感兴趣的文章:</b><ul><li>C#使用DataSet Datatable更新数据库的三种实现方法</li><li>C#中遍历DataSet数据集对象实例</li><li>C#读取数据库返回泛型集合详解(DataSetToList)</li><li>C#检测DataSet是否为空的方法</li><li>C#中DataSet、DataTable、DataRow数据的复制方法</li><li>C#遍历DataSet控件实例总结</li></ul>
                            </div>

                        </div>
                        <!--endmain-->
頁: [1]
查看完整版本: c#中DataSet类的具体使用