I have 2 DataTables with no primary keys on either table. I need all records in DataTable1 to be left joined with DataTable2. I've solved it a couple of ways but are they performant?
Column2 is the soft "key" and I am trying to populate the column 3 field in DataTable1 from DataTable2.
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
DataTable dt1 = new DataTable();
dt1.Columns.Add("col1", typeof(int));
dt1.Columns.Add("col2", typeof(string));
dt1.Columns.Add("col3", typeof(string));
dt1.Rows.Add(1, "One");
dt1.Rows.Add(1, "Two");
dt1.Rows.Add(3, "Two");
DataTable dt2 = new DataTable();
dt2.Columns.Add("col1", typeof(int));
dt2.Columns.Add("col2", typeof(string));
dt2.Columns.Add("col3", typeof(string));
dt2.Rows.Add(1, "One", "One Description");
dt2.Rows.Add(2, "Two", "Two Description");
//Solution 1
//foreach (DataRow row in dt1.Rows)
//{
// row[2] = dt2.Select("col2='" + row[1] + "'")[0]["col3"];
//}
foreach (DataRow row in dt1.Rows)
{
row[2] = dt2.AsEnumerable().Where(x => x["col2"] == row[1]).FirstOrDefault()[2];
}
dt1.AsEnumerable().ToList().ForEach(x =>
Console.WriteLine(
"col1:{0} col2:{1} col3:{2}"
, x[0], x[1], x[2])
);
}
}
}
Bonus: I tried to copy this into .Net Fiddle but it doesn't seem to like the AsEnumerable on the DataTable. Go .Net Fiddle
You can use LINQ GroupJoin for that:
var result = dt1.Select()
.GroupJoin(dt2.Select(), t1 => t1[1], t2 => t2[1], (t1, t2) => { t1[2] = t2.FirstOrDefault()?[2]; return t1; })
.ToList();
Related
I'm trying to combine 3 table into 1 datagridview but i want some spesific columns from each table
these are my tables
a.Malzemeler
-Malzeme_ID (PK)
-Malzemeİsmi
-Gram_mL
-Adet
-BirimFiyat
-ToplamFiyat
b.Tarifler
-Tarif_ID (PK)
-Tarif_İsmi
-Talimatlar
c.TariflerveMalzemeler
-ID
-Tarif_ID (FK)
-Malzeme_ID (FK)
-Gram_mL
-Adet
what i want to do is
d.Result
-Tarif_İsmi (From table b)
-Malzeme_İsmi (from table a)
-Gram_mL(From table c)
-Adet (from table c)
-Talimatlar (From Table b)
My select query work on SQL
"SELECT Tarif_İsmi,Malzemeİsmi, TariflerveMalzemeler.Gram_mL, TariflerveMalzemeler.Adet, Talimatlar FROM Malzemeler
JOIN TariflerveMalzemeler ON Malzemeler.Malzeme_ID = TariflerveMalzemeler.Malzeme_ID JOIN Tarifler ON TariflerveMalzemeler.Tarif_ID = Tarifler.Tarif_ID"
but i dont know how to make it work on datagridview ?
Try following :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
namespace ConsoleApplication166
{
class Program
{
static void Main(string[] args)
{
DataTable Malzemeler = new DataTable();
Malzemeler.Columns.Add("Malzeme_ID", typeof(string));
Malzemeler.Columns.Add("Malzemeİsmi", typeof(string));
Malzemeler.Columns.Add("Gram_mL", typeof(string));
Malzemeler.Columns.Add("Adet", typeof(string));
Malzemeler.Columns.Add("BirimFiyat", typeof(string));
Malzemeler.Columns.Add("ToplamFiyat", typeof(string));
DataTable Tarifler = new DataTable();
Tarifler.Columns.Add("Tarif_ID", typeof(string));
Tarifler.Columns.Add("Tarif_İsmi", typeof(string));
Tarifler.Columns.Add("Talimatlar", typeof(string));
DataTable TariflerveMalzemeler = new DataTable();
TariflerveMalzemeler.Columns.Add("ID", typeof(string));
TariflerveMalzemeler.Columns.Add("Tarif_ID", typeof(string));
TariflerveMalzemeler.Columns.Add("Malzeme_ID", typeof(string));
TariflerveMalzemeler.Columns.Add("Gram_mL", typeof(string));
TariflerveMalzemeler.Columns.Add("Adet", typeof(string));
DataTable Result = new DataTable();
Result.Columns.Add("Tarif_İsmi", typeof(string));
Result.Columns.Add("Malzeme_İsmi", typeof(string));
Result.Columns.Add("Gram_mL", typeof(string));
Result.Columns.Add("Adet", typeof(string));
Result.Columns.Add("Talimatlar", typeof(string));
var joins = from tm in TariflerveMalzemeler.AsEnumerable()
join m in Malzemeler.AsEnumerable() on tm.Field<string>("Malzeme_ID") equals m.Field<string>("Malzeme_ID")
join t in Tarifler.AsEnumerable() on tm.Field<string>("Tarif_ID") equals t.Field<string>("Tarif_ID")
select new { tm = tm, m = m, t = t};
foreach (var j in joins)
{
Result.Rows.Add(new object[] {
j.t.Field<string>("Tarif_İsmi"),
j.m.Field<string>("Malzeme_İsmi"),
j.tm.Field<string>("Gram_mL"),
j.tm.Field<string>("Adet"),
j.t.Field<string>("Talimatlar")
});
}
}
}
}
I want to rearrange query result from db with duplicate data into distinct row (for data display )but having 1 column collect related values in comma separated if more than 1 item found.
For example consider list below (from db query):
ID GROUP DATE
A1212 1 1/1/2019
A1212 2 1/1/2019
A1313 1 3/1/2019
into:
ID GROUP
A1212 1,2
A1313 1
sql string:
select DISTINCT Declaration_Form_Master.*,Declaration_Form_Detail.KPA_Group, Temp_Storage_Reg_V.*,Temp_Storage_Reg_V.ID as TSEID,Users.Company As Uc, 'NULL' as 'CTU_id' from Declaration_Form_Master left outer join Temp_Storage_Reg_V on (Declaration_Form_Master.Master_ID=Temp_Storage_Reg_V.TSEMaster_ID) right join Users on (Declaration_Form_Master.Agent_ID = Users.UserId) right join Declaration_Form_Detail on (Declaration_Form_Master.Master_ID = Declaration_Form_Detail.Master_ID) where Declaration_Form_Master.Confirmation ='1' and Submit_Date >= '2019-01-28' and Submit_Date < '2019-08-30' order by Application_ID DESC
need to join all table because search criteria based on column on multiple table. i cant figure out on sql, but want to rearrange back the result using array or list.
Maybe some algorithm can help.
Try following :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
DataTable dt = new DataTable();
dt.Columns.Add("ID", typeof(string));
dt.Columns.Add("GROUP", typeof(int));
dt.Columns.Add("DATE", typeof(DateTime));
dt.Rows.Add(new object[] {"A1212", 1, DateTime.Parse("1/1/2019")});
dt.Rows.Add(new object[] {"A1212", 2, DateTime.Parse("1/1/2019")});
dt.Rows.Add(new object[] {"A1213", 1, DateTime.Parse("3/1/2019")});
DataTable dt2 = new DataTable();
dt2.Columns.Add("ID", typeof(string));
dt2.Columns.Add("GROUP", typeof(string));
var groups = dt.AsEnumerable().GroupBy(x => x.Field<string>("ID")).ToList();
foreach (var group in groups)
{
dt2.Rows.Add(new object[] {
group.Key,
string.Join(",", group.Select(x => x.Field<int>("GROUP").ToString()).Distinct())
});
}
}
}
}
If you want to do this action even in T-SQL you must aggregate the result
By exemple
DECLARE #fakeTable TABLE (ID varchar(50), [GROUP] int)
INSERT INTO #fakeTable
VALUES
('A1212', 1 ),
('A1212', 2 ),
('A1213', 1 )
SELECT
ID,
[GROUP] = stuff((
SELECT ','+convert(varchar(100),[GROUP])
FROM #fakeTable innerTable
WHERE innerTable.ID = orgTable.ID
ORDER BY [GROUP]
for xml path (''), type).value('.','nvarchar(max)')
,1,1,'')
FROM (
SELECT DISTINCT ID FROM #fakeTable
) orgTable
More info about aggregation
DataTable dx = new DataTable();
dx.Columns.Add("Application_ID", typeof(int));
dx.Columns.Add("KPA_Group", typeof(int));
foreach(var z in data) {
dx.Rows.Add(new object[] { z.Application_ID,z.KPA_Group });
}
DataTable dt1 = new DataTable();
dt1.Columns.Add("Application_ID", typeof(string));
dt1.Columns.Add("KPA_Group", typeof(string));
var groups = dx.AsEnumerable().GroupBy(x => x.Field<Int32>("Application_ID")).ToList();
foreach (var group in groups)
{
dt1.Rows.Add(new object[] {
group.Key,
string.Join(",", group.Select(x => x.Field<int>("KPA_Group").ToString()).Distinct())
});
}
foreach (DataRow row in dt1.Rows)
{
#:#row["Application_ID"].ToString() |
#:#row["KPA_Group"] <br />
}
result :
2019080001 | 2,3
2019070002 | 2
2019070001 | 2
2019060001 | 1,2
2019040002 | 2
2019030002 | 2
2019030001 | 2
2019020002 | 2
2019020001 | 2
i dont understand why i can't use CopyToDataTable method. solved this by using foreach.
How to Change dataTable Rows to Columns
DataTable dt=new DataTable();
dt = getData(); //Pull data from source file
I have below format rows in a dataTable.
Now I want change ANC_TYPE rows into columns?
How i can convert into below format ?
You want a pivot table :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
namespace ConsoleApplication49
{
class Program
{
static void Main(string[] args)
{
DataTable dt = new DataTable();
dt.Columns.Add("OPR_DT", typeof(DateTime));
dt.Columns.Add("OPR_HR", typeof(int));
dt.Columns.Add("ANC_TYPE", typeof(string));
dt.Columns.Add("ANC_REGION", typeof(string));
dt.Columns.Add("MARKET_RUN_ID", typeof(string));
dt.Columns.Add("XML_DATE_ITEM", typeof(string));
dt.Columns.Add("MW", typeof(decimal));
dt.Columns.Add("GROUP", typeof(int));
dt.Rows.Add(new object[] { DateTime.Parse("2/23/2017"), 1, "NR", "AS_CAISO_EXP", "DAM", "NS_CLR_PRC", 0.09, 1});
dt.Rows.Add(new object[] { DateTime.Parse("2/23/2017"), 1, "RD", "AS_CAISO_EXP", "DAM", "RD_CLR_PRC", 2.83, 2 });
dt.Rows.Add(new object[] { DateTime.Parse("2/23/2017"), 2, "NR", "AS_CAISO_EXP", "DAM", "NS_CLR_PRC", 0.01, 3 });
dt.Rows.Add(new object[] { DateTime.Parse("2/23/2017"), 2, "RD", "AS_CAISO_EXP", "DAM", "RD_CLR_PRC", 0.1, 4 });
string[] uniqueAncType = dt.AsEnumerable().Select(x => x.Field<string>("ANC_TYPE")).Distinct().ToArray();
DataTable pivot = new DataTable();
pivot.Columns.Add("OPR_DT", typeof(DateTime));
pivot.Columns.Add("OPR_HR", typeof(int));
pivot.Columns.Add("ANC_REGION", typeof(string));
pivot.Columns.Add("MARKET_RUN_ID", typeof(string));
foreach (string col in uniqueAncType)
{
pivot.Columns.Add(col, typeof(string));
}
var groups = dt.AsEnumerable()
.GroupBy(x => new {
opr_dt = x.Field<DateTime>("OPR_DT"),
opr_hr = x.Field<int>("OPR_HR"),
anc_region = x.Field<string>("ANC_REGION"),
run_id = x.Field<string>("MARKET_RUN_ID")
}).ToList();
foreach (var group in groups)
{
DataRow newRow = pivot.Rows.Add();
newRow["OPR_DT"] = group.Key.opr_dt;
newRow["OPR_HR"] = group.Key.opr_hr;
newRow["ANC_REGION"] = group.Key.anc_region;
newRow["MARKET_RUN_ID"] = group.Key.run_id;
foreach (DataRow ancType in group)
{
newRow[ancType.Field<string>("ANC_TYPE")] = ancType.Field<decimal>("MW");
}
}
}
}
}
how to add two datatables?
(dt1=name,phone_number)
and
(dt2=address,cityname)
Result:
(dt3=name,phone_number,address,cityname)
Ruben, you will need some primary key in order to combine both tables unless you are 100% sure that both data tables have the same number of rows and they will always be stored in the correct order.
There is a similar question answered and the link is: Combining n DataTables into a Single DataTable
Here goes the content of the provided link:
"The table has repeating primary keys after the Merge because no primary-key was defined. So either specify the PK or try this method here which i've written from scratch(so it's not really tested):
public static DataTable MergeAll(this IList<DataTable> tables, String primaryKeyColumn)
{
if (!tables.Any())
throw new ArgumentException("Tables must not be empty", "tables");
if(primaryKeyColumn != null)
foreach(DataTable t in tables)
if(!t.Columns.Contains(primaryKeyColumn))
throw new ArgumentException("All tables must have the specified primarykey column " + primaryKeyColumn, "primaryKeyColumn");
if(tables.Count == 1)
return tables[0];
DataTable table = new DataTable("TblUnion");
table.BeginLoadData(); // Turns off notifications, index maintenance, and constraints while loading data
foreach (DataTable t in tables)
{
table.Merge(t); // same as table.Merge(t, false, MissingSchemaAction.Add);
}
table.EndLoadData();
if (primaryKeyColumn != null)
{
// since we might have no real primary keys defined, the rows now might have repeating fields
// so now we're going to "join" these rows ...
var pkGroups = table.AsEnumerable()
.GroupBy(r => r[primaryKeyColumn]);
var dupGroups = pkGroups.Where(g => g.Count() > 1);
foreach (var grpDup in dupGroups)
{
// use first row and modify it
DataRow firstRow = grpDup.First();
foreach (DataColumn c in table.Columns)
{
if (firstRow.IsNull(c))
{
DataRow firstNotNullRow = grpDup.Skip(1).FirstOrDefault(r => !r.IsNull(c));
if (firstNotNullRow != null)
firstRow[c] = firstNotNullRow[c];
}
}
// remove all but first row
var rowsToRemove = grpDup.Skip(1);
foreach(DataRow rowToRemove in rowsToRemove)
table.Rows.Remove(rowToRemove);
}
}
return table;
}
You can call it in this way:
var tables = new[] { tblA, tblB, tblC };
DataTable TblUnion = tables.MergeAll("c1");
Used this sample data:
var tblA = new DataTable();
tblA.Columns.Add("c1", typeof(int));
tblA.Columns.Add("c2", typeof(int));
tblA.Columns.Add("c3", typeof(string));
tblA.Columns.Add("c4", typeof(char));
var tblB = new DataTable();
tblB.Columns.Add("c1", typeof(int));
tblB.Columns.Add("c5", typeof(int));
tblB.Columns.Add("c6", typeof(string));
tblB.Columns.Add("c7", typeof(char));
var tblC = new DataTable();
tblC.Columns.Add("c1", typeof(int));
tblC.Columns.Add("c8", typeof(int));
tblC.Columns.Add("c9", typeof(string));
tblC.Columns.Add("c10", typeof(char));
tblA.Rows.Add(1, 8500, "abc", 'A');
tblA.Rows.Add(2, 950, "cde", 'B');
tblA.Rows.Add(3, 150, "efg", 'C');
tblA.Rows.Add(4, 850, "ghi", 'D');
tblA.Rows.Add(5, 50, "ijk", 'E');
tblB.Rows.Add(1, 7500, "klm", 'F');
tblB.Rows.Add(2, 900, "mno", 'G');
tblB.Rows.Add(3, 150, "opq", 'H');
tblB.Rows.Add(4, 850, "qrs", 'I');
tblB.Rows.Add(5, 50, "stu", 'J');
tblC.Rows.Add(1, 7500, "uvw", 'K');
tblC.Rows.Add(2, 900, "wxy", 'L');
tblC.Rows.Add(3, 150, "yza", 'M');
tblC.Rows.Add(4, 850, "ABC", 'N');
tblC.Rows.Add(5, 50, "CDE", 'O');
After DataTable.Merge in MergeAll:
After some modifications to join the rows in MergeAll:
Update
Since this question arose in one of the comments, if the only relation between two tables is the index of a DataRow in the table and you want to merge both tables according to the index:
public static DataTable MergeTablesByIndex(DataTable t1, DataTable t2)
{
if (t1 == null || t2 == null) throw new ArgumentNullException("t1 or t2", "Both tables must not be null");
DataTable t3 = t1.Clone(); // first add columns from table1
foreach (DataColumn col in t2.Columns)
{
string newColumnName = col.ColumnName;
int colNum = 1;
while (t3.Columns.Contains(newColumnName))
{
newColumnName = string.Format("{0}_{1}", col.ColumnName, ++colNum);
}
t3.Columns.Add(newColumnName, col.DataType);
}
var mergedRows = t1.AsEnumerable().Zip(t2.AsEnumerable(),
(r1, r2) => r1.ItemArray.Concat(r2.ItemArray).ToArray());
foreach (object[] rowFields in mergedRows)
t3.Rows.Add(rowFields);
return t3;
}
Sample:
var dt1 = new DataTable();
dt1.Columns.Add("ID", typeof(int));
dt1.Columns.Add("Name", typeof(string));
dt1.Rows.Add(1, "Jon");
var dt2 = new DataTable();
dt2.Columns.Add("Country", typeof(string));
dt2.Rows.Add("US");
var dtMerged = MergeTablesByIndex(dt1, dt2);
The result table contains three columns ID,Name,Country and a single row: 1 Jon US"
Source: Combining n DataTables into a Single DataTable
Last Access: 04-August-2016
First you can filter right column in to separate data datable
DataTable filterDatatable1= new DataTable();
DataTable filterDatatable2= new DataTable();
DataTable filterDatatable1= OriginaDatatable1.DefaultView.ToTable(false, "ColumnName1", "ColimnName2");
DataTable filterDatatable1= OriginaDatatable1.DefaultView.ToTable(false, "ColumnName1", "ColimnName2", "ColimnName3");
Then you can use merge function
DataTable dtAll = new DataTable();
dtAll.Merge(filterDatatable1);
dtAll.Merge(filterDatatable2);
All, there are some question on this, but I can't seem to extract enough information to solve the problem for my case. I extract an unknown number of tables into SQL Server 'Tab1', 'Tab2', 'Tab3', ... , 'TabN'. The columns in these tables are different, but the row definitions are the same. I need to pull all the data in from the Server into N DataTables and then combine these to form a single DataTable. What I do currently is
int nTmpVolTabIdx = 1;
strSqlTmp = String.Empty;
using (DataTable dataTableALL = new DataTable())
{
while (true)
{
string strTmpVolName = String.Format("Tab{0}", nTmpVolTabIdx);
strSqlTmp = String.Format("SELECT * FROM [{0}];", strTmpVolName);
// Pull the data from 'VolX' into a local DataTable.
using (DataTable dataTable = UtilsDB.DTFromDB(conn, strTmpVolName, strSqlTmp, false))
{
if (dataTable == null)
break;
else
dataTableALL.Merge(dataTable);
}
nTmpVolTabIdx++;
}
...
}
This merges the DataTables but they are miss-aligned (padding blank cells onto the appended data set). I could append the columns of the new DataTable via a loop; but is there an easier/nicer way to do this (perhaps using LINQ)?
Thanks for your time.
Edit. To provide the example data sets.
What I required is
The individual tables are
After the first Merge operation I have the following
Thanks again.
The table has repeating primary keys after the Merge because no primary-key was defined. So either specify the PK or try this method here which i've written from scratch(so it's not really tested):
public static DataTable MergeAll(this IList<DataTable> tables, String primaryKeyColumn)
{
if (!tables.Any())
throw new ArgumentException("Tables must not be empty", "tables");
if(primaryKeyColumn != null)
foreach(DataTable t in tables)
if(!t.Columns.Contains(primaryKeyColumn))
throw new ArgumentException("All tables must have the specified primarykey column " + primaryKeyColumn, "primaryKeyColumn");
if(tables.Count == 1)
return tables[0];
DataTable table = new DataTable("TblUnion");
table.BeginLoadData(); // Turns off notifications, index maintenance, and constraints while loading data
foreach (DataTable t in tables)
{
table.Merge(t); // same as table.Merge(t, false, MissingSchemaAction.Add);
}
table.EndLoadData();
if (primaryKeyColumn != null)
{
// since we might have no real primary keys defined, the rows now might have repeating fields
// so now we're going to "join" these rows ...
var pkGroups = table.AsEnumerable()
.GroupBy(r => r[primaryKeyColumn]);
var dupGroups = pkGroups.Where(g => g.Count() > 1);
foreach (var grpDup in dupGroups)
{
// use first row and modify it
DataRow firstRow = grpDup.First();
foreach (DataColumn c in table.Columns)
{
if (firstRow.IsNull(c))
{
DataRow firstNotNullRow = grpDup.Skip(1).FirstOrDefault(r => !r.IsNull(c));
if (firstNotNullRow != null)
firstRow[c] = firstNotNullRow[c];
}
}
// remove all but first row
var rowsToRemove = grpDup.Skip(1);
foreach(DataRow rowToRemove in rowsToRemove)
table.Rows.Remove(rowToRemove);
}
}
return table;
}
You can call it in this way:
var tables = new[] { tblA, tblB, tblC };
DataTable TblUnion = tables.MergeAll("c1");
Used this sample data:
var tblA = new DataTable();
tblA.Columns.Add("c1", typeof(int));
tblA.Columns.Add("c2", typeof(int));
tblA.Columns.Add("c3", typeof(string));
tblA.Columns.Add("c4", typeof(char));
var tblB = new DataTable();
tblB.Columns.Add("c1", typeof(int));
tblB.Columns.Add("c5", typeof(int));
tblB.Columns.Add("c6", typeof(string));
tblB.Columns.Add("c7", typeof(char));
var tblC = new DataTable();
tblC.Columns.Add("c1", typeof(int));
tblC.Columns.Add("c8", typeof(int));
tblC.Columns.Add("c9", typeof(string));
tblC.Columns.Add("c10", typeof(char));
tblA.Rows.Add(1, 8500, "abc", 'A');
tblA.Rows.Add(2, 950, "cde", 'B');
tblA.Rows.Add(3, 150, "efg", 'C');
tblA.Rows.Add(4, 850, "ghi", 'D');
tblA.Rows.Add(5, 50, "ijk", 'E');
tblB.Rows.Add(1, 7500, "klm", 'F');
tblB.Rows.Add(2, 900, "mno", 'G');
tblB.Rows.Add(3, 150, "opq", 'H');
tblB.Rows.Add(4, 850, "qrs", 'I');
tblB.Rows.Add(5, 50, "stu", 'J');
tblC.Rows.Add(1, 7500, "uvw", 'K');
tblC.Rows.Add(2, 900, "wxy", 'L');
tblC.Rows.Add(3, 150, "yza", 'M');
tblC.Rows.Add(4, 850, "ABC", 'N');
tblC.Rows.Add(5, 50, "CDE", 'O');
After DataTable.Merge in MergeAll:
After some modifications to join the rows in MergeAll:
Update
Since this question arose in one of the comments, if the only relation between two tables is the index of a DataRow in the table and you want to merge both tables according to the index:
public static DataTable MergeTablesByIndex(DataTable t1, DataTable t2)
{
if (t1 == null || t2 == null) throw new ArgumentNullException("t1 or t2", "Both tables must not be null");
DataTable t3 = t1.Clone(); // first add columns from table1
foreach (DataColumn col in t2.Columns)
{
string newColumnName = col.ColumnName;
int colNum = 1;
while (t3.Columns.Contains(newColumnName))
{
newColumnName = string.Format("{0}_{1}", col.ColumnName, ++colNum);
}
t3.Columns.Add(newColumnName, col.DataType);
}
var mergedRows = t1.AsEnumerable().Zip(t2.AsEnumerable(),
(r1, r2) => r1.ItemArray.Concat(r2.ItemArray).ToArray());
foreach (object[] rowFields in mergedRows)
t3.Rows.Add(rowFields);
return t3;
}
Sample:
var dt1 = new DataTable();
dt1.Columns.Add("ID", typeof(int));
dt1.Columns.Add("Name", typeof(string));
dt1.Rows.Add(1, "Jon");
var dt2 = new DataTable();
dt2.Columns.Add("Country", typeof(string));
dt2.Rows.Add("US");
var dtMerged = MergeTablesByIndex(dt1, dt2);
The result table contains three columns ID,Name,Country and a single row: 1 Jon US