two datatable adding - c#

I have two datatables.
1st table-----> DataTable _dtMain = new COrder().GetDetails();
2nd table-----> DataTable _dtSub = new CGrid().GetSubDetails();
I want to add the above two tables. I am using _dtMain.Merge(_dtSub );
But it will append _dtSub table to _dtMain table. I want datatable to add second table to first table in column wise (that means after first table last column)

Don't think there any built-in method for the thing you want to achieve.
I think you need to make your own implementation for that stuff, like for example an extension method
public static DataTable Aggregate(this DataTable dt1, DataTable dt2)
{
var aggregator = new DataTable();
//add columns from dt1 and dt2
//add rows from dt1 dt2
}
or, you can do a complete Outer Join on both tables, like descrived in this article.

After a lot of research , i find out the answer for my question that i posted before. Here is the code for combing 2 datatable & the data inside it.
public DataTable CombineTable(DataTable _dtGridDetails, DataTable _dtSubGridDetails)
{
//first create the datatable columns
DataSet mydataSet = new DataSet();
mydataSet.Tables.Add(" ");
DataTable myDataTable = mydataSet.Tables[0];
//add left table columns
DataColumn[] dcLeftTableColumns = new DataColumn[_dtGridDetails.Columns.Count];
_dtGridDetails.Columns.CopyTo(dcLeftTableColumns, 0);
foreach (DataColumn LeftTableColumn in dcLeftTableColumns)
{
if (!myDataTable.Columns.Contains(LeftTableColumn.ToString()))
myDataTable.Columns.Add(LeftTableColumn.ToString());
}
//now add right table columns
DataColumn[] dcRightTableColumns = new DataColumn[_dtSubGridDetails.Columns.Count];
_dtSubGridDetails.Columns.CopyTo(dcRightTableColumns, 0);
foreach (DataColumn RightTableColumn in dcRightTableColumns)
{
if (!myDataTable.Columns.Contains(RightTableColumn.ToString()))
{
// if (RightTableColumn.ToString() != RightPrimaryColumn)
myDataTable.Columns.Add(RightTableColumn.ToString());
}
}
//add left-table data to mytable
foreach (DataRow LeftTableDataRows in _dtGridDetails.Rows)
{
myDataTable.ImportRow(LeftTableDataRows);
}
for (int nIndex = 0; nIndex <= myDataTable.Rows.Count-1; nIndex++)
{
if (nIndex == _dtSubGridDetails.Rows.Count)
break;
myDataTable.Rows[nIndex][columnindex] = _dtSubGridDetails.Rows[nIndex][columnindex];
}
return myDataTable;
}

Related

c# split one datatable to several into dataset

I have correct source DataTable "sourceDataTable" and I call method to split it into several and store the result into DataSet "ds":
DataSet ds = MyClass.SplitDataTables(sourceDataTable);
Here is the method MyClass.SplitDataTables():
public static DataSet SplitDataTables(DataTable sourceDataTable)
{
using (DataSet dsOut = new DataSet())
{
DataTable dt1 = new DataTable;
DataTable dt2 = new DataTable;
DataTable dt3 = new DataTable;
dt1 = sourceDataTable.Clone();
dt2 = sourceDataTable.Clone();
dt3 = sourceDataTable.Clone();
foreach (DataRow row in sourceDataTable.Rows)
{
//column is for example "City" and some row has "Boston" in it, so I put this row into dt1
if (row["ColumnName"].ToString() == "something")
{
dt1.ImportRow(row);
}
else if (...)
{ } //for other DataTables dt2, dt3, etc...
else .......... ;
}
//here I put resulting DataTables into one DataSet which is returned
string[] cols= { "dt1", "dt2", "dt3" };
foreach (string col in cols)
{
dsOut.Tables.Add(col);
}
return dsOut;
}
}
So with this returned DataSet I display new Windows each with one DataTable
foreach (DataTable dtt in ds.Tables)
{
string msg = dtt.TableName;
Window2 win2 = new Window2(dtt, msg);
win2.Show();
}
All I get shown is Windows with placeholder for "empty DataGrid"
Windows code is correct, as it works whith "unsplit DataTable".
I assume code in splitting DataTables is all wrong as it does not output DataSet with filled DataTables. I will greatly appreciate any help on this issue. Thank you!
You don't need a for loop here
Replace below code
string[] cols= { "dt1", "dt2", "dt3" };
foreach (string col in cols)
{
dsOut.Tables.Add(col);
}
With this
dsOut.Tables.Add(dt1);
dsOut.Tables.Add(dt2);
dsOut.Tables.Add(dt3);
Thanks to #Krishna I got this solved. So if you ever encounter similar problem here are 2 things to note:
string[] cols = { "dt1", "dt2", "dt3", ... };
foreach (string col in cols)
{
dsOut.Tables.Add(col);
}
This cycle does not have access to objects of DataTables with same name and writes only empty DataTables into DataSet collection (regardless of same name!).
If you create new DataTable and you will be making it a clone of another DataTable, dont bother yet with setting its name.
DataTable dt1 = new DataTable();
Make new DataTable of same format as source DataTable:
dt1 = sourceDataTable.Clone();
dt2 = sourceDataTable.Clone();
//etc...
Now you have to set unique DataTable names to each DataTable cloned from source DataTable:
dt1.TableName = "Name1";
dt2.TableName = "Name2";
//and so on
Now all works as intended.

Create a datatable column between two column in C#

I have a Datatable. For example :
private DataTable GetGenericDatatable(){
DataTable retval = new DataTable();
retval.Columns.Add("ProtocolNumber");
retval.Columns.Add("Name");
retval.Columns.Add("Company");
retval.Columns.Add("Department");
retval.Columns.Add("VisitDate");
retval.Columns.Add("DispatchTargetName");
retval.Columns.Add("DayOffCount");
// add data ...
return retval;
}
I want to insert some columns between "Department" and "VisitDate" columns dynamically even the datatable is full with data.
We can do this by creating new datatable, creating the columns again etc. but it is a dirty solution. Any idea for a clear solution?
You can assign a DefaultValue to the DataColumm:
DataTable tbl = GetGenericDatatable();
tbl.Columns.Add(new DataColumn("Col1") { DefaultValue="def. value"});
tbl.Columns.Add(new DataColumn("Col2", typeof(DateTime)) { DefaultValue = DateTime.Now });
This value will be applied to every existing row in the table.
You can use SetOrdinal to set the index of a column. For example:
tbl.Columns["Col1"].SetOrdinal(tbl.Columns.IndexOf("VisitDate"));
tbl.Columns["Col2"].SetOrdinal(tbl.Columns.IndexOf("VisitDate"));
Now the new columns are between Department and VisitDate, Col1 before Col2.
Add a new DataColumn and use the SetOrdinal method to set its position:
var col = retval.Columns.Add("New Column");
col.SetOrdinal(4);
You could use this Extension:
namespace System
{
public static class Extensions
{
public static void AddColumnAfter(this DataColumnCollection columnCollection, string afterWhichColumn, DataColumn column)
{
var columnIndex = columnCollection.IndexOf(afterWhichColumn);
columnCollection.Add(column);
columnCollection[column.ColumnName].SetOrdinal(columnIndex + 1);
}
}
}
Example:
DataTable table = new DataTable();
table.Columns.Add("Column 1");
table.Columns.Add("Column 2");
table.Columns.Add("Column 3");
table.Columns.AddColumnAfter("Column 1", new DataColumn("Column 4"));

Join 2 DataTables into 1 in C# [duplicate]

This question already has answers here:
how to join two datatable datas into one datatable to show in one gridview in asp.net
(4 answers)
Closed 9 years ago.
I have two identical DataTables from two different databases (but the ids are unique!). So now I want to have combine this data into a single DataTable. I have no idea what to do.
I tried the following:
DataTable one = new DataTable();
one = baza_win.pobierz_dane("SELECT...");
DataTable two = new DataTable();
two = baza_win2.pobierz_dane("SELECT...");
//DataTable sum = one + two;
DataTable sum = new DataTable();
sum.Clone(one);
sum.Merge(two,false);
But this doesn't work at sum.Clone(one);
Any ideas?
sum = one.Copy();
sum.Merge(two);
I think you need Copy instead of Clone:
DataTable one = new DataTable();
one = baza_win.pobierz_dane("SELECT...");
DataTable two = new DataTable();
two = baza_win2.pobierz_dane("SELECT...");
//DataTable sum = one + two;
DataTable sum = new DataTable();
sum.Copy(one);
sum.Merge(two,false);
copied from link
http://msdn.microsoft.com/en-us/library/fk68ew7b.aspx
duplicate of
how to join two datatable datas into one datatable to show in one gridview in asp.net
private static void DemonstrateMergeTable()
{
DataTable table1 = new DataTable("Items");
// Add columns
DataColumn column1 = new DataColumn("id", typeof(System.Int32));
DataColumn column2 = new DataColumn("item", typeof(System.Int32));
table1.Columns.Add(column1);
table1.Columns.Add(column2);
// Set the primary key column.
table1.PrimaryKey = new DataColumn[] { column1 };
// Add RowChanged event handler for the table.
table1.RowChanged +=
new System.Data.DataRowChangeEventHandler(Row_Changed);
// Add some rows.
DataRow row;
for (int i = 0; i <= 3; i++)
{
row = table1.NewRow();
row["id"] = i;
row["item"] = i;
table1.Rows.Add(row);
}
// Accept changes.
table1.AcceptChanges();
PrintValues(table1, "Original values");
// Create a second DataTable identical to the first.
DataTable table2 = table1.Clone();
// Add three rows. Note that the id column can't be the
// same as existing rows in the original table.
row = table2.NewRow();
row["id"] = 14;
row["item"] = 774;
table2.Rows.Add(row);
row = table2.NewRow();
row["id"] = 12;
row["item"] = 555;
table2.Rows.Add(row);
row = table2.NewRow();
row["id"] = 13;
row["item"] = 665;
table2.Rows.Add(row);
// Merge table2 into the table1.
Console.WriteLine("Merging");
table1.Merge(table2);
PrintValues(table1, "Merged With table1");
}
private static void Row_Changed(object sender,
DataRowChangeEventArgs e)
{
Console.WriteLine("Row changed {0}\t{1}",
e.Action, e.Row.ItemArray[0]);
}
private static void PrintValues(DataTable table, string label)
{
// Display the values in the supplied DataTable:
Console.WriteLine(label);
foreach (DataRow row in table.Rows)
{
foreach (DataColumn col in table.Columns)
{
Console.Write("\t " + row[col].ToString());
}
Console.WriteLine();
}
}
try the following... CLONE the first table so it has proper structure, THEN merge two into it.
DataTable sum = one.Clone()
sum.Merge(two,false);

Copying data of only few columns to one more data table

I have a scenario where I get a data table with 65 columns and 100 rows. I need to create one more data table with all 100 rows, i.e. the same as the original data table but should be having only 5 columns out of 65 present in original table. Is there any way to achieve this without looping?
Try DataView.ToTable method.
Use it like this:
DataTable newTable = oldTable.DefaultView.ToTable(false, "ColumnName1", "ColumnName2", "ColumnName3", "ColumnName4", "ColumnName5");
DataTable oldTable = new DataTable();
DataTable newTable = oldTable.Copy();
for (int i = 5; i < 65; i++)
{
newTable.Columns.RemoveAt(i);
}
Try like this,
DataTable newTable = oldTable.Copy();
newTable.Columns.Remove("ColumnName");
You remove the unwanted columns here.
Here is the best Solution for your Question:
DataTable dt = new DataTable();
string [] column = {"Column1", "Column2"};
dt = DTItem.DefaultView.ToTable("dd", false, column);
//DTItem is the Existing Table and "dd" is the temporary tablename, u give whatever u want
lets assume we want to create a new datatable and grab first four columns of an existing datatable and put it in new datatable.
private void button3_Click(object sender, EventArgs e)
{
DataTable destiny = new DataTable();
destiny.Columns.Add("c1");//set the columns you want to copy
destiny.Columns.Add("c2");
destiny.Columns.Add("c3");
destiny.Columns.Add("c4");
CopyColumns(dtST_Split, destiny, "c1", "c2","c3","c4");
}
// function to copy all rows but just specific columns from table 1 to table 2
private void CopyColumns(DataTable source, DataTable dest, params string[] columns)
{
foreach (DataRow sourcerow in source.Rows)
{
DataRow destRow = dest.NewRow();
foreach (string colname in columns)
{
destRow[colname] = sourcerow[colname];
}
dest.Rows.Add(destRow);
}
}

How to get columns from a datarow?

I have a row collection (DataRow[] rows). And I want to import all rows to another DataTable (DataTable dt).
But how?
Code
DataTable dt;
if (drs.Length>0)
{
dt = new DataTable();
foreach (DataRow row in drs)
{
dt.Columns.Add(row???????)
}
// If it possible, something like that => dt.Columns.AddRange(????????)
for(int i = 0; i < drs.Length; i++)
{
dt.ImportRow(drs[i]);
}
}
Assuming the rows all have the same structure, the easiest option is to clone the old table, omitting the data:
DataTable dt = drs[0].Table.Clone();
Alternatively, something like:
foreach(DataColumn col in drs[0].Table.Columns)
{
dt.Columns.Add(col.ColumnName, col.DataType, col.Expression);
}
If your DataRows is from a Data Table with Columns defined in it,
DataRow[] rows;
DataTable table = new DataTable();
var columns = rows[0].Table.Columns;
table.Columns.AddRange(columns.Cast<DataColumn>().ToArray());
foreach (var row in rows)
{
table.Rows.Add(row.ItemArray);
}
How about
DataTable dt = new DataTable;
foreach(DataRow dr in drs)
{
dt.ImportRow(dr);
}
Note this only works if drs is a DataRowCollection. Detached rows (not in a DataRowCollection are ignored).
Don't forget to call AcceptChanges.
Try this:
// Assuming you have a DataRow object named row:
foreach(DataColumn col in row.Table.Columns)
{
// Do whatever you need to with these columns
}

Categories