将DataTable中的一行复制到另一个DataTable

本文介绍了两种将DataTable中的一行复制到另一个DataTable的有效方法。方法1使用DataRow对象进行逐项复制,而方法2则直接导入行数据,适用于需要在不同DataTable间迁移数据的场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

将DataTable中的一行复制到另一个DataTable

方法1:

        DataRow dr = ds2.Tables[0].NewRow();
        dr.ItemArray = ds1.Tables[0].Rows[i].ItemArray;
        ds2.Tables[0].Rows.Add( dr ); 

方法2:

     ds2.Tables[0].ImportRow(ds1.Tables[0].Rows[i]);

<think>我们之前已经讨论过如何将一行一个DataTable复制到一个DataTable。但是,用户现在要求复制“指定行”,可能是指根据某些条件选择特定的行进行复制。 以下是几种常见情况的解决方案: 1. 复制单行(根据索引或条件) 2. 复制多行(根据条件筛选) 3. 复制整个DataTable(但用户要求指定行,所以重点在前两个) 我们将提供两种主要方法: - 使用ImportRow(当两个DataTable结构相同时) - 手动创建新行并复制(当结构不同时) 同时,我们也会考虑使用LINQ来筛选要复制的行。 注意:复制行时,如果目标有主键约束,可能会引发唯一性冲突,需要处理。 下面给出具体代码示例。</think># C# 复制 DataTable 指定行到一个 DataTable 在 C# 中复制 DataTable 的指定行到一个 DataTable 有多种方法,具体取决于结构是否相同以及选择行的方式。以下是几种常见场景的解决方案: ## 方法 1:复制单行(结构相同) 当源和目标结构完全相同时,可以使用 `ImportRow` 方法: ```csharp using System; using System.Data; class Program { static void Main() { // 创建源并添加数据 DataTable sourceTable = CreateSampleTable(); sourceTable.Rows.Add(1, "Alice", 30); sourceTable.Rows.Add(2, "Bob", 25); sourceTable.Rows.Add(3, "Charlie", 35); // 创建目标(相同结构) DataTable targetTable = sourceTable.Clone(); // 选择要复制的行(例如索引为1的行) DataRow selectedRow = sourceTable.Rows[1]; // 复制行到目标 targetTable.ImportRow(selectedRow); // 打印结果 PrintTable("源", sourceTable); PrintTable("目标", targetTable); } static DataTable CreateSampleTable() { DataTable table = new DataTable("People"); table.Columns.Add("ID", typeof(int)); table.Columns.Add("Name", typeof(string)); table.Columns.Add("Age", typeof(int)); return table; } static void PrintTable(string title, DataTable table) { Console.WriteLine($"\n{title} ({table.TableName}):"); foreach (DataRow row in table.Rows) { Console.WriteLine($"ID: {row["ID"]}, Name: {row["Name"]}, Age: {row["Age"]}"); } } } ``` ## 方法 2:复制多行(使用条件筛选) 使用 LINQ 选择符合条件的多行并复制: ```csharp using System; using System.Data; using System.Linq; class Program { static void Main() { DataTable sourceTable = CreateSampleTable(); sourceTable.Rows.Add(1, "Alice", 30); sourceTable.Rows.Add(2, "Bob", 25); sourceTable.Rows.Add(3, "Charlie", 35); sourceTable.Rows.Add(4, "David", 28); // 创建目标(相同结构) DataTable targetTable = sourceTable.Clone(); // 使用 LINQ 选择年龄大于28的行 var selectedRows = sourceTable.AsEnumerable() .Where(row => row.Field<int>("Age") > 28) .ToList(); // 复制中的行 foreach (DataRow row in selectedRows) { targetTable.ImportRow(row); } // 打印结果 PrintTable("源", sourceTable); PrintTable("目标 (年龄>28)", targetTable); } // CreateSampleTable 和 PrintTable 方法同上 } ``` ## 方法 3:复制行到结构不同的 当目标结构不同时,需要手动映射字段: ```csharp // 创建目标(不同结构) DataTable targetTable = new DataTable("PersonInfo"); targetTable.Columns.Add("PersonID", typeof(int)); targetTable.Columns.Add("FullName", typeof(string)); targetTable.Columns.Add("AgeGroup", typeof(string)); // 选择要复制的行(索引0和2) DataRow[] selectedRows = { sourceTable.Rows[0], sourceTable.Rows[2] }; foreach (DataRow sourceRow in selectedRows) { // 创建新行并映射字段 DataRow newRow = targetTable.NewRow(); newRow["PersonID"] = sourceRow["ID"]; newRow["FullName"] = sourceRow["Name"]; // 计算新字段值 int age = (int)sourceRow["Age"]; newRow["AgeGroup"] = age < 30 ? "Young" : "Adult"; targetTable.Rows.Add(newRow); } ``` ## 方法 4:复制行并保留原始行状态 如果需要保留行的原始状态(如 Modified、Unchanged 等): ```csharp // 创建目标(相同结构) DataTable targetTable = sourceTable.Clone(); // 选择要复制的行(所有未更改的行) var unchangedRows = sourceTable.AsEnumerable() .Where(row => row.RowState == DataRowState.Unchanged); // 复制行并保留状态 foreach (DataRow row in unchangedRows) { // 创建新行并复制值 DataRow newRow = targetTable.NewRow(); newRow.ItemArray = row.ItemArray; // 设置行状态 newRow.AcceptChanges(); if (row.RowState == DataRowState.Modified) { newRow.SetModified(); } targetTable.Rows.Add(newRow); } ``` ## 方法 5:使用扩展方法(通用解决方案) 创建可重用的扩展方法处理不同场景: ```csharp using System; using System.Collections.Generic; using System.Data; using System.Linq; public static class DataTableExtensions { // 复制指定行到目标(自动处理结构差异) public static void CopyRowsTo(this DataTable source, DataTable target, IEnumerable<DataRow> rowsToCopy) { foreach (DataRow sourceRow in rowsToCopy) { if (source.Columns.Count == target.Columns.Count && source.Columns.Cast<DataColumn>().SequenceEqual(target.Columns.Cast<DataColumn>(), new ColumnComparer())) { // 结构相同,直接导入 target.ImportRow(sourceRow); } else { // 结构不同,手动映射 DataRow newRow = target.NewRow(); foreach (DataColumn targetCol in target.Columns) { if (source.Columns.Contains(targetCol.ColumnName)) { object value = sourceRow[targetCol.ColumnName]; newRow[targetCol.ColumnName] = value; } // 可添加默认值或转换逻辑 } target.Rows.Add(newRow); } } } // 比较两个列是否相同(名称和类型) private class ColumnComparer : IEqualityComparer<DataColumn> { public bool Equals(DataColumn x, DataColumn y) { return x.ColumnName == y.ColumnName && x.DataType == y.DataType; } public int GetHashCode(DataColumn obj) { return obj.ColumnName.GetHashCode() ^ obj.DataType.GetHashCode(); } } } // 使用示例 var selectedRows = sourceTable.AsEnumerable().Take(2); // 选择前两行 sourceTable.CopyRowsTo(targetTable, selectedRows); ``` ## 注意事项 1. **主键冲突**:如果目标有主键约束,添加重复行会抛出异常 2. **性能优化**:复制大量数据时,使用 `BeginLoadData()` 和 `EndLoadData()` 3. **行状态**:`ImportRow()` 会保留原始行状态,手动创建的行状态为 `Added` 4. **数据引用**:复制行不会复制相关的子行(ChildRows) 5. **类型安全**:确保源值和目标列数据类型兼容 ##
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值