在 C# 中加入数据表
Joining DataTables in C#
我是 C# 和 .net 的新手。这是我的问题
我有两个数据表,每个只有一列
dtTab1 -
col1
a
c
dtTab2 -
col2
p
q
现在我想将它们合并成一个结果 table 应该看起来像这样
dtResult - col1 col2
a p
c q
我试过了
dtResult.Merge(dtTab1, false, MissingSchemaAction.Ignore);
dtResult.Merge(dtTab2, false, MissingSchemaAction.Ignore);
但出于某种原因,它创建了 4 行而不是两行。
请帮忙。
谢谢
表之间没有定义关系,所以Merge
只是将它们连接起来。
您可以手动添加:
DataTable dtResult = new DataTable();
foreach (DataColumn col in dtTab1.Columns)
dtResult.Columns.Add(col.ColumnName, col.DataType);
foreach (DataColumn col in dtTab2.Columns)
dtResult.Columns.Add(col.ColumnName, col.DataType);
for (int r = 0; r < Math.Min(dtTab1.Rows.Count, dtTab2.Rows.Count); r++)
{
DataRow r1 = dtTab1.Rows[r];
DataRow r2 = dtTab2.Rows[r];
DataRow row = dtResult.Rows.Add();
foreach (DataColumn col in dtTab1.Columns)
row.SetField(col.ColumnName, r1[col]);
foreach (DataColumn col in dtTab2.Columns)
row.SetField(col.ColumnName, r2[col]);
}
表之间没有关系,但可以根据索引连接它们。
试一试:
DataTable dt1 = new DataTable();
DataColumn dc = new DataColumn("col1", Type.GetType("System.String"));
dt1.Columns.Add(dc);
dt1.Rows.Add(new Object[]{"a"});
dt1.Rows.Add(new Object[]{"c"});
DataTable dt2 = new DataTable();
dc = new DataColumn("col2", Type.GetType("System.String"));
dt2.Columns.Add(dc);
dt2.Rows.Add(new Object[]{"p"});
dt2.Rows.Add(new Object[]{"q"});
DataTable dtResult = new DataTable();
dc = new DataColumn("index", Type.GetType("System.Int32"));
dtResult.Columns.Add(dc);
dc = new DataColumn("col1", Type.GetType("System.String"));
dtResult.Columns.Add(dc);
dc = new DataColumn("col2", Type.GetType("System.String"));
dtResult.Columns.Add(dc);
var dtRows = from r1 in dt1.AsEnumerable().Select((x,y)=>new{col1 = x.Field<string>("col1"), index = y})
join r2 in dt2.AsEnumerable().Select((x,y)=>new{col2 = x.Field<string>("col2"), index = y}) on r1.index equals r2.index
select dtResult.LoadDataRow(new Object[]{r1.index, r1.col1, r2.col2}, true);
dtRows.CopyToDataTable();
dtResult.Dump();
注意:以上代码已在LinqPad中创建。
结果:
index col1 col2
0 a p
1 c q
这是一个更紧凑(也更简单)的版本,应该可以满足您的需求。
DataTable result = new DataTable();
result.Columns.Add("col1", typeof(object));
result.Columns.Add("col2", typeof(object));
// assuming both data tables have the same length
for (int row = 0; row < dtTab1.Rows.Count; row++)
{
DataRow dr;
dr = result.NewRow();
dr[0] = dtTab1.Rows[row][0];
dr[1] = dtTab2.Rows[row][0];
result.Rows.Add(dr);
}
您可以调整 result.Columns.Add 以使用您的 table 需要的 Db 类型创建 table。
result.Columns.Add(new DataColumn("col2", Type.GetType("System.String")));
感谢大家的帮助。 Tim 的解决方案让我最接近答案,但这是我最终设法解决它的方法
DataTable dtResult = new DataTable();
DataColumn col = null;
string ColName = string.Empty;
int i;
int ColCnt = 1;
dtResult.Clear();
dtResult.Columns.Clear();
for (i = 0; i < dtTab1.Columns.Count; i++)
{
ColName = dtTab1.Columns[i].ColumnName;
col = new DataColumn(ColName);
col.DataType = System.Type.GetType("System.String");
dtResult.Columns.Add(col);
ColCnt++;
}
for (i = 0; i < dtTab2.Columns.Count; i++)
{
ColName = dtTab2.Columns[i].ColumnName;
col = new DataColumn(ColName);
col.DataType = System.Type.GetType("System.String");
dtResult.Columns.Add(col);
ColCnt++;
}
object[] elems = new object[dtTab1.Columns.Count + dtTab2.Columns.Count];
for (int r = 0; r < Math.Min(dtTab1.Rows.Count, dtTab2.Rows.Count); r++)
{
DataRow r1 = dtTab1.Rows[r];
DataRow r2 = dtTab2.Rows[r];
DataRow row ;
int q = 0;
for (; q < dtTab1.Columns.Count; q++)
elems[q] = r1.ItemArray[q];
int z = 0;
for (; z < dtTab2.Columns.Count; z++)
elems[q + z] = r2.ItemArray[z];
row = dtResult.NewRow();
row.ItemArray = elems;
dtResult.Rows.Add(row);
}
蒂姆,你的解决方案确实帮助我理解了流程,但出于某种原因,我在
处收到了一个 ArgumentException
row.SetField(col.ColumnName, r1[col]);
我是 C# 和 .net 的新手。这是我的问题
我有两个数据表,每个只有一列
dtTab1 -
col1
a
c
dtTab2 -
col2
p
q
现在我想将它们合并成一个结果 table 应该看起来像这样
dtResult - col1 col2
a p
c q
我试过了
dtResult.Merge(dtTab1, false, MissingSchemaAction.Ignore);
dtResult.Merge(dtTab2, false, MissingSchemaAction.Ignore);
但出于某种原因,它创建了 4 行而不是两行。
请帮忙。
谢谢
表之间没有定义关系,所以Merge
只是将它们连接起来。
您可以手动添加:
DataTable dtResult = new DataTable();
foreach (DataColumn col in dtTab1.Columns)
dtResult.Columns.Add(col.ColumnName, col.DataType);
foreach (DataColumn col in dtTab2.Columns)
dtResult.Columns.Add(col.ColumnName, col.DataType);
for (int r = 0; r < Math.Min(dtTab1.Rows.Count, dtTab2.Rows.Count); r++)
{
DataRow r1 = dtTab1.Rows[r];
DataRow r2 = dtTab2.Rows[r];
DataRow row = dtResult.Rows.Add();
foreach (DataColumn col in dtTab1.Columns)
row.SetField(col.ColumnName, r1[col]);
foreach (DataColumn col in dtTab2.Columns)
row.SetField(col.ColumnName, r2[col]);
}
表之间没有关系,但可以根据索引连接它们。
试一试:
DataTable dt1 = new DataTable();
DataColumn dc = new DataColumn("col1", Type.GetType("System.String"));
dt1.Columns.Add(dc);
dt1.Rows.Add(new Object[]{"a"});
dt1.Rows.Add(new Object[]{"c"});
DataTable dt2 = new DataTable();
dc = new DataColumn("col2", Type.GetType("System.String"));
dt2.Columns.Add(dc);
dt2.Rows.Add(new Object[]{"p"});
dt2.Rows.Add(new Object[]{"q"});
DataTable dtResult = new DataTable();
dc = new DataColumn("index", Type.GetType("System.Int32"));
dtResult.Columns.Add(dc);
dc = new DataColumn("col1", Type.GetType("System.String"));
dtResult.Columns.Add(dc);
dc = new DataColumn("col2", Type.GetType("System.String"));
dtResult.Columns.Add(dc);
var dtRows = from r1 in dt1.AsEnumerable().Select((x,y)=>new{col1 = x.Field<string>("col1"), index = y})
join r2 in dt2.AsEnumerable().Select((x,y)=>new{col2 = x.Field<string>("col2"), index = y}) on r1.index equals r2.index
select dtResult.LoadDataRow(new Object[]{r1.index, r1.col1, r2.col2}, true);
dtRows.CopyToDataTable();
dtResult.Dump();
注意:以上代码已在LinqPad中创建。
结果:
index col1 col2
0 a p
1 c q
这是一个更紧凑(也更简单)的版本,应该可以满足您的需求。
DataTable result = new DataTable();
result.Columns.Add("col1", typeof(object));
result.Columns.Add("col2", typeof(object));
// assuming both data tables have the same length
for (int row = 0; row < dtTab1.Rows.Count; row++)
{
DataRow dr;
dr = result.NewRow();
dr[0] = dtTab1.Rows[row][0];
dr[1] = dtTab2.Rows[row][0];
result.Rows.Add(dr);
}
您可以调整 result.Columns.Add 以使用您的 table 需要的 Db 类型创建 table。
result.Columns.Add(new DataColumn("col2", Type.GetType("System.String")));
感谢大家的帮助。 Tim 的解决方案让我最接近答案,但这是我最终设法解决它的方法
DataTable dtResult = new DataTable();
DataColumn col = null;
string ColName = string.Empty;
int i;
int ColCnt = 1;
dtResult.Clear();
dtResult.Columns.Clear();
for (i = 0; i < dtTab1.Columns.Count; i++)
{
ColName = dtTab1.Columns[i].ColumnName;
col = new DataColumn(ColName);
col.DataType = System.Type.GetType("System.String");
dtResult.Columns.Add(col);
ColCnt++;
}
for (i = 0; i < dtTab2.Columns.Count; i++)
{
ColName = dtTab2.Columns[i].ColumnName;
col = new DataColumn(ColName);
col.DataType = System.Type.GetType("System.String");
dtResult.Columns.Add(col);
ColCnt++;
}
object[] elems = new object[dtTab1.Columns.Count + dtTab2.Columns.Count];
for (int r = 0; r < Math.Min(dtTab1.Rows.Count, dtTab2.Rows.Count); r++)
{
DataRow r1 = dtTab1.Rows[r];
DataRow r2 = dtTab2.Rows[r];
DataRow row ;
int q = 0;
for (; q < dtTab1.Columns.Count; q++)
elems[q] = r1.ItemArray[q];
int z = 0;
for (; z < dtTab2.Columns.Count; z++)
elems[q + z] = r2.ItemArray[z];
row = dtResult.NewRow();
row.ItemArray = elems;
dtResult.Rows.Add(row);
}
蒂姆,你的解决方案确实帮助我理解了流程,但出于某种原因,我在
处收到了一个 ArgumentExceptionrow.SetField(col.ColumnName, r1[col]);