I want to assign a DataTable (dataTable1) to another DataTable (dataTable2) and remove some columns in the latter DataTable. For example I have the following code:
DataTable dataTable2 = dataTable1;
dataTable2.Columns.Remove("column1");
dataTable2.Columns.Remove("column2");
It turns out both DataTable (dataTable1 and dataTable2) have the columns removed. I do not understand why dataTable1 would have column1 and column2 removed as well, while I am only removing columns in dataTable2.
[EDITED - with answer]
Should use Clone() AND ImportRow() instead of a pointer assignment.
DataTable dataTable2 = dataTable1.Clone()
for (int i = 0; i < dataTable1.Rows.Count; i++)
{
dataTable2.ImportRow(dataTable1.Rows[i]);
}
This happens because dataTable2 points to the same table as dataTable1. To resolve this problem, use the DataTable's Clone method to create a new DataTable with the same structure:
DataTable dataTable2 = dataTable1.Clone();
dataTable2.Columns.Remove("column1");
dataTable2.Columns.Remove("column2");
datatable is reference type so thats why both of the tables are changing if changes are made in one. and instead of looping through data rows you could either call dataTable1.Copy() to copy data and schema to another datatable.
datatable.clone() is pass by reference. u have to give it by value.
DataTable dataTable2=dataTable1.Copy();
dataTable2.Columns.Remove("column1");
dataTable2.Columns.Remove("column2");
Now removing From datatable2 does not effect DataTable1
Related
I want to copy first row of one DataTable to first row of another DataTable. I did as shown below but it throws error like
Property or indexer 'System.Data.DataRowCollection.this[int]' cannot be assigned to -- it is read only
DataTable dt = GetTable();
DataTable dt1 = GetTable1();
dt.Rows[0] = dt1.Rows[0];
You have to copy it field by field.
The data row within the datatable is immutable, which means that you can change the values of its fields, but not the object itself, being said that you should copy the values from you source row to the destination row.
Assuming your datatables have the same columns:
DataTable dt = GetTable();
DataTable dt1 = GetTable1();
foreach(DataColumn column in dt.Columns)
{
dt.Rows[0][column] = dt1.Rows[0][column];
}
Hope this helps.
I have a problem.Let's explain this:
I create a DataTable 'DataT' variable and added row to this variable.SameTime i have datagridview. After i assingmented 'DataT' to DataSource property of DataGridView.
I get 'DataT' Rows.Count property.It's value 10.But this value decrease from 10 to 5 when i removed 5 Rows of DataGridView.
So why decrease my value i just remove Rows of DataGridView but i did not remove rows of 'DataT' although rows count of 'DataT' decrease from 10 to 5.
I have not solve this problem.
EDIT:
Yes i bound datatable.But same problem there is other state.I explain with a example:
DataTable Table1 = new DataTable();
DataTable Table2 = new DataTable();
DataRow Rows;
private void Form1_Load(.......)
{
Tablo1.Columns.Add("Column1");
Tablo1.Columns.Add("Column2");
Rows = Table1.NewRow();
Rows[0] = "Hello";
Rows[1] = "Word";
Table1.Rows.Add(Rows);
Rows = Table1.NewRow();
Rows[0] = "Hello";
Rows[1] = "Word";
Table1.Rows.Add(Rows);
Table2 = Table1;
datagridview1.DataSource = Table1;
//This datagridview1 has 2 Rows and Table1 has 2 Rows.
datagridview1.Rows.RemoveAt(0);
//I am Removing one Row of datagridview1.Not from Table1.
//But Automatic removing Rows from Table1.
//Result=datagridview1 has 1 Row and Table1 has 1 Row.Why do remove rows from Table1?
//Even Rows Remove from Table2 when i remove rows from datagridview1.
}
As Henk Holterman pointed out in comment there are two reasons making Table2 to change
since Table1 is used as DataSource for grid any changes in the grid will be reflected in it. This is expected behavior of GridView.
GridView has its own Rows collection that is updated when one sets DataSource. Any changes to Rows collection (like removing item) are applied to DataTable set as data source. As result datagridview1.Rows.RemoveAt(0); actually indirectly removes row from the object referenced by Table1.
Both of your variables (Table1 and Table2) point to the same object - so whenever anything happens to the DataTable (i.e. row removed by GridView) the change is visible when you check either of variables.
Following code performs "shallow copy" when you seem to expect complete clone similar to behavior of int:
Table2 = Table1;
After that assignment both Table1 and Table2 refer to DataTable created on DataTable Table1 = new DataTable(); line.
See more What is the difference between a deep copy and a shallow copy?
I'm trying to do something like this to create copy of a typed datarow:
var desRow = dataTable.NewRow();
var sourceRow = dataTable.Rows[rowNum];
desRow.ItemArray = sourceRow.ItemArray.Clone() as object[];
But when I call dataTable.Clear() method it clears all fields in desRow. How to create a deep copy of a DataRow?
In your code when you create your new row you create with that row a reference to the dataTable and that is why it clears all fields.
You can work with a data table clone, that way you will have a deep copy.
DataTable dt = ...
DataTable cloneDt = dt.Clone();
DataRow row = cloneDt.Rows[number];
dt.Rows.Clear();
dt.Rows.Add(row);
This way you will have your original data table with only the selected row.
I would copy a DataColumn from a DataTable into a another DataTable, but I don't know how to do...
DataColumn[] dc = new DataColumn[DataTable1.Columns.Count];
DataTable1.Columns.CopyTo(dc, 0);
DataTable2.Columns.Add(dc[index]);
Error
DataColumn belongs to another DataTable!
You could use the DataView.ToTable method that accepts the column names that you want to have in your new table.
DataTable DataTable2 = DataTable1.DefaultView.ToTable(false, new string[] {"CustomerName"});
Keep in mind that this creates a new DataTable from your original table with only the column specified in the string array (of course the original table should have a column named "CustomerName")
Ok, now! Removing the columns was a realy bad idea!
Much better for the columns in a DataTable:
DataGrid2.Columns[index].Visibility = System.Windows.Visibility.Collapsed;
DataGrid2.Columns[index].Visibility = System.Windows.Visibility.Visible;
And for the rows in an DataTable:
DataRow dataRow = DataTable2.NewRow();
object o = DataTable1.Rows[index].ItemArray.GetValue(index);
dataRow.SetField(index, o);
DataTable2.Rows.InsertAt(dataRow, 0);
((DataRowView)(DataGrid2.Items[index])).Row.Delete();
Thanks!
i have a datable and like this i have searched a datarow from the datable on the basis of some primary now i want to add that searched row to another datatable how can i achieve this please let me know
DataTable findRows = (DataTable)ViewState["dt"];
List<int> selectedList=(List<int>)ViewState["selectedList"];
DataTable temp = new DataTable();
foreach (int id in selectedList)
{
DataRow dr=findRows.Rows.Find(id);
}
now i want it to add to datatable temp how can i achieve this?
First, when creating temp don't just instantiate it as a new DataTable but instead call .Clone() on findrows to create a structurally identical DataTable.
Second, use .ImportRow() on the second DataTable and pass it the row from the first DataTable that you'd like to copy. This should create an entirely new row in the second table with the same values as the row from the first table.