Avoid a column when checking DataRowState for a DataRow - c#

Is there any way in C# to check if the datatable values are changed or not from the time it is loaded from DB ? But I know we can check the DataRowState to identify it. But here I want to avoid or neglect a particular column when checking the DataRowState for a DataRow. Simple code is shown here.
foreach (DataRow dr in DataTable.Rows)
{
if (dr.RowState != DataRowState.Unchanged)
{
// code
}
}
When checking the DataRowState for a DataRow, how can i neglect or avoid a column and check all the values of the other columns in the DataRow ?
Something like as shown below :
// avoid Status column value and consider all other column values in the row.
foreach (DataRow dr in DataTable.Rows.Where(not Status column))
{
if (dr.RowState != DataRowState.Unchanged)
{
// code
}
}

You can get all record that chenged with this code:
DataSet changedRecords = dataSet1.GetChanges();

Related

adding a column to a specific row in dataset

I have a dataset.
I want to iterate it and add a column (currently not in my dataset) with different value to every row. More specificly, i want it to be at 0 index.
I want to check the value in "fullname" column, and then add a new column with Id.
What do i need to write?
I iterate like this:
foreach (DataRow theRow in mesakem.Tables["fullname"].Rows)
foreach(oved o in ovdimlist)
if(o.name==theRow.ToString())
add column(o.id)......
Ty very much!
I think you meant to insert a new column at index 0 and then add id values to cell for each row where current name cell value matches your object name. If I'm right, it should look like this:
DataColumn col = mesakem.Tables["fullname"].Columns.Add("Id");
col.SetOrdinal(0);
foreach (DataRow row in mesakem.Tables["fullname"].Rows)
{
foreach (oved o in ovdimlist)
{
if (o.name == row["Name"].ToString())
row["Id"] = o.id;
}
}

GetChanges from merged datatables returns null

I have following code:
DataTable datTable3 = new DataTable();
datTable3 = datTable1.Clone();
datTable2.Merge(datTable1);
datTable3 = datTable2.GetChanges();
Want I want to do is: Compare DataTable1 with DataTable2 and when there are rows in DataTable1 which aren't in DataTable 2 then add these rows into a new DataTable(3). This code above gives me an empty DataTable3 each time although the rows in the first dt are not equal to the rows in my second dt. what am I doing wrong? Sorry if that question may be too easy but I'm using C# since a couple of months.
EDIT: I found this solution which doesn't work for me... Why?
DataTable datTable3 = new DataTable();
datTable3 = datTable1.Clone();
foreach (DataRow row in datTable1.Rows)
{
datTable3.ImportRow(row);
}
foreach (DataRow row in datTable3.Rows)
{
row.SetAdded();
}
datTable2.Merge(datTable3);
DataTable datTableFinal = datTable2.GetChanges(DataRowState.Added);
// shows me a datatable with again the values from datTable1
// even if they are already in datTable2!
datTable2.RejectChanges();
datTable1.RejectChanges();
The DataTable.GetChanges() method Gets a copy of the DataTable that contains all changes made to it since it was loaded or AcceptChanges was last called.
In other words, GetChanges() is dependent on the DataRow.RowState property. A DataTable.Merge() will either preserve their 'RowState' property, or reset it to 'Unchanged'.
This means that when you merge two DataTables with rows that have 'Unchanged' RowStates, the merged table will also contain 'Unchanged' rows and the DataTable.GetChanges method will return null or Nothing.
EDIT : You can always iterate through the DataTable to see what rows are added to the merged table. Something like
foreach(DataRow row in datTable2.Rows)
{
Console.WriteLine("--- Row ---"); // Print separator.
foreach (var item in row.ItemArray) // Loop over the items.
{
Console.Write("Item: "); // Print label.
Console.WriteLine(item); // Invokes ToString abstract method.
}
}
Iterate through and use LoadDataRow(object[] value, bool fAcceptChanges) :
foreach (DataRow row in MergeTable.Rows)
{
TargetTable.LoadDataRow(row.ItemArray, false);
}
var changes = TargetTable.GetChanges();
changes had the desired value when I tried this method.

Error in DataTable row deletion

i have a datatable say DT having 11rows and i tried to delete rows having id=3 using
string DeptID ="3";
string s = "id='" + DeptID + "'";
rows = DT.Select(s);
foreach (DataRow r in rows)
r.Delete();
i am having 5 rows having id=3 but after deletion the number of rows in datatable not changed and some red color symbol comes in each fields(columns) of the deleted rows.Can anyone know why this is happening?
and whenever i tried to acces the remaining rows using
for(int i=0;i<dt1.Rows.Count;i++)
{
if (dt1.Rows[i][0].ToString() == "")
{
}
}
it shows error 'deleted rows cannot take'
After deleting the rows,please give Acceptchanges() to the datatable,so that,it will get synchronized with new data.
dt.AcceptChanges();
//And u can also add a condition,while fetching the data,
foreach (DataRow dr in rows)
{ if(dr.RowState!=DataRowState.Deleted ||dr.RowState!=DataRowState.Detached)
{
}
}
You marked the row for deletion, that's why the red color symbols appear. row.Delete() only changes your row state to Deleted. When you accept then changes (via AcceptChanges method), the actual deletion will occur.
For more information, these are some msdn links:
http://msdn.microsoft.com/en-us/library/03c7a3zb.aspx
http://msdn.microsoft.com/en-us/library/system.data.datarow.delete.aspx
http://msdn.microsoft.com/en-us/library/system.data.datarow.acceptchanges.aspx

Exception in copying DataRow to another DataTable

I have two data tables, dt1 & dt2. dt1 has data while dt2 is a new table. Now I want to copy some rows, satisfying particular condition, to dt2. I have tried following code, but I get this exception:
System.ArgumentException This row already belongs to another table.
foreach(DataRow dr in dt1.Rows)
{
if(Convert.ToInt32(dr["col"]) == value)
{
dt2.Rows.Add(dr);
}
}
How can I resolve this?
change dt2.Rows.Add(dr); to dt2.Rows.Add(dr.ItemArray);
You directly cannot "Add" a DataTable row from one to another since it belongs to souce Datatable. You can "Add" a newly created row to DataTable.
Hence you are getting this exception.
There are many ways to overcome this. Some are listed below
Method 1:
If you want to get a row from source Datatable and add in destination without any changes, then use ImportRow this way.
dt2.ImportRow(dr);
Method 2:
But if you want to take specific data. Then use this
foreach(DataRow dr in dt1.Rows)
{
if(Convert.ToInt32(dr["col"]) == value)
{
Datarow ndr = dt2.NewRow();
ndr["Foo"] = dr["Foo"];
//..Similarly for other rows.
dt2.Rows.Add(ndr);
}
}
Every time when you add a row to the datatable it should be different(new) row........
Datarow newRow = null;
foreach(DataRow dr in dt1.Rows)
{
if(Convert.ToInt32(dr["col"]) == value)
{
newRow = dt2.NewRow();
newRow ["A"] = dr["A"];
dt2.Rows.Add(newRow );
}
}

Loop through each row in a column find a null value and replace in a datatable c#

I am trying to write a linq query or another way that will loop through all the rows in a column within a data table.
The data column header is known in advanced. As it loops I want to be able to check for a null value in each cell and if found put a default value in, in the case below it is [dob].
Below is an example of a dataTable, I want to able to loop through the [dob] column and look for the null value and replace it with a default value say 01/01/1901.
[firstName], [lastname], [dob]
tester, testerSurname, null
tester2, tester2Surname, 25/04/1876
foreach (DataColumn column in table.Columns)
{
if (table.Rows.OfType<DataRow>().Any(r => r.IsNull(column)))
{
}
I have started above but could not find away of getting the value and assigning it to another value but could find the null.
You wouldn't loop through each row in a column, you would just loop through the rows and check that column for each row in the loop:
DataTable dt;
string col = "ColumnIAmCheckingForANullValue";
string def = "My Default Value for NULL";
foreach (DataRow row in dt.Rows) {
if (string.IsNullOrEmpty(row[col].ToString())) {
row[col] = def;
}
}
If you're looking to perform a bulk database update, a Linq query is not the best way to go about it. You're better off writing a SQL query to perform the update - the COALESCE operator will be your friend.
UPDATE tablename
SET dob = COALESCE(dob, '1901/01/01')
If u r using data table then u can also loop through columns in a row
foreach (DataRow dr in table.Rows)
{
foreach (DataColumn clm in table.Columns)
{
if (dr[clm] == DBNull.Value)
{
dr[clm] = GetDefaultValueForColumn[clm.ColumnName];
}
}
}
If checking for DBNull, the code from mikeschuld's answer should work:
DataTable dt;
string col = "ColumnIAmCheckingForANullValue";
string anotherValue = "My Default Value for NULL";
foreach (DataRow row in dt.Rows) {
if (row[col] is DBNull) {
row[col] = anotherValue;
}
}
You can remove NULL from data using query
SELECT ISNULL(col, '') FROM MyTable

Categories

Resources