0

how to add two datatables?

(dt1=name,phone_number) 

and

(dt2=address,cityname) 

Result:

(dt3=name,phone_number,address,cityname)
Zein Makki
  • 29,485
  • 6
  • 52
  • 63
Ruben rj
  • 27
  • 1
  • 11
  • Do `d1` and `d2` have the same number of rows ? Or are you matching rows from the two tables based on some column ? Please provide a clear and complete example. – Zein Makki Aug 04 '16 at 05:11

2 Answers2

0

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:

Print after Merge in MergeAll

After some modifications to join the rows in MergeAll:

Print after some modifications

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

Community
  • 1
  • 1
Daniel Santana
  • 1,493
  • 20
  • 19
0

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);
Nalaka
  • 1,165
  • 7
  • 12