[英]Copy datatable as columns in another datatable
我有几个DataTable,我需要将它们复制到另一个DataTable中。 例如,正如您在附图中看到的那样,我需要从源表1中获取所有数据并将其复制到Dest Table的前2列中,在接下来的2列中复制Source Table 2,依此类推。 如何轻松实现这一目标?
编辑:我必须阅读几个excel文件(我将每个文件存储在数据表中),我不知道我将拥有多少源表,因此必须以某种方式动态完成。
假设您的源表具有相同的结构,您可以使用Table.Copy()创建dest表,然后在循环中复制数据:
List<DataTable> sourceTables = getYourSourceTablesMethod();
if (sourceTables.Length>0)
{
DataTable destTable = sourceTables[0].Copy();
for (int i = 1; i < sourceTables; i++)
{
foreach (DataRow drow in sourceTables[i].Rows)
destTable.Rows.Add(drow.ItemArray);
}
}
您可以使用框架提供的Merge方法,用于使用和额外信息,请参阅Microsoft Datatable Merge
您应该找到该源表之间的关系。 例如,它们具有相同的ID,您可以像这样复制它们
insert into destTable(
select s1.col1, s1.col2, s2.col3, s2.col4, s3.col5, s3.col6, s4.col7, s4.col8
from sourcetable1 s1, sourcetable2 s2, sourcetable3 s3, sourcetable4 s4
where s1.id = s2.id and s2.id = s3.id and s3.id = s4.id)
您可以触发以下查询:
select col1,col2 into sourcetable1 from destTable
union
select col3,col4 into sourcetable2 from destTable
union
select col5,col6 into sourcetable3 from destTable
union
select col7,col8 into sourcetable4 from destTable
或者,可以按照这里提到的技术。
在数据行的情况下,它可以是:
foreach (DataRow row in DestTable)
{
SourceTable1.ImportRow(row);
}
您可以先创建目标表,添加它的列(通过汇总所有输入表中的列数),然后通过连接输入表中每行的各个值数组来添加它的行。
当然,结果DataTable
行将包含每个输入表在顶部向下方向显示的值(在顶部对齐)。 它还意味着结果行的数量是最大输入表中的行数。
首先,我们将初始化并填充List<DataTable>
变量,然后我们将使用此变量作为方法参数执行连接:
#region table collection initialization
List<DataTable> dts = new List<DataTable>();
var dt = new DataTable();
dt.Columns.Add("Test0", typeof(string));
dt.Rows.Add(1);
dt.Rows.Add(2);
dts.Add(dt);
dt = new DataTable();
dt.Columns.Add("Test1", typeof(int));
dt.Rows.Add(2);
dts.Add(dt);
dt = new DataTable();
dt.Columns.Add("Test3", typeof(int));
dt.Columns.Add("Test4");
dt.Columns.Add("Test5", typeof(int));
dt.Rows.Add(3, "a", 1);
dt.Rows.Add(4);
dt.Rows.Add(5, "a");
dt.Rows.Add(null, "a");
dts.Add(dt);
dt = new DataTable();
dt.Columns.Add("Test6", typeof(DateTime));
dt.Columns.Add("Test7", typeof(int));
dt.Rows.Add(DateTime.Now);
dts.Add(dt);
#endregion
// sample method usage
var result = GetJoinedTable(dts);
让我们创建GetJoinedTable
方法,该方法将result
连接表返回到result
变量中:
private DataTable GetJoinedTable(List<DataTable> dts)
{
var dest = new DataTable();
//will be used if you have non-unique column names
int counter = 0;
foreach (var column in dts
.SelectMany<DataTable, DataColumn>(t =>
t.Columns.Cast<DataColumn>()))
{
dest.Columns.Add(column.ColumnName, column.DataType);
// if you have non-unique column names use the following instead
//dest.Columns.Add(String.Format("column_{0}", counter++),
// column.DataType);
}
List<object> rowItems;
for (int i = 0; i < dts.Max(t => t.Rows.Count); i++)
{
rowItems = new List<object>();
for (int j = 0; j < dts.Count; j++)
{
if (dts[j].Rows.Count > i)
{
var r = dts[j].Rows[i].ItemArray
.Select((v, index) =>
(v == null || v == System.DBNull.Value)
? GetDefault(dts[j].Columns[index].DataType) : v);
rowItems.AddRange(r);
}
else
{
for (int c = 0; c < dts[j].Columns.Count; c++)
{
rowItems.Add(GetDefault(dts[j].Columns[c].DataType));
}
}
}
dest.Rows.Add(rowItems.ToArray());
}
return dest;
}
您还需要添加以下方法,该方法根据列的DataType
属性返回相应的默认列值:
object GetDefault(Type t)
{
if (t.IsValueType)
{
return Activator.CreateInstance(t);
}
else
{
return null;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.