Access deleted rows from a DataTable

I have a parent WinForm with MyDataTable _dt as a member. The MyDataTable type was created in the "typed dataset" constructor tool in Visual Studio 2005 (MyDataTable inherits from DataTable) _dt populated from db via ADO.NET. Based on the changes in user interaction on the form, I delete the row from the table as follows:

_dt.FindBySomeKey(_someKey).Delete();

Later _dt is passed by value to the dialog form. From there, I need to scan all the lines in order to build the line:

  foreach (myDataTableRow row in _dt) { sbFilter.Append("'" + row.info + "',"); } 

The problem is that after this, the following exception is DeletedRowInaccessibleException: Deleted row information cannot be accessed through the row. after deletion: DeletedRowInaccessibleException: Deleted row information cannot be accessed through the row.

The work I'm currently using (which looks like a hack) is this:

  foreach (myDataTableRow row in _dt) { if (row.RowState != DataRowState.Deleted && row.RowState != DataRowState.Detached) { sbFilter.Append("'" + row.info + "',"); } } 

My question is: Is this the right way to do this? Why were the access strings for the foreach loop marked with the Delete() method?

+7
c # datatable
source share
5 answers

You will need to check:

  _dt.DefaultView.RowStateFilter 

I think that the default settings will not display deleted lines, maybe you will change them somewhere.

You can always create an additional RowView and manage its filter and make your own loop over the view.

+2
source share

Delete method marks the line to be deleted; the string is not actually deleted until you name AcceptChanges .

Instead, call _dt.Rows.Remove(_dt.FindBySomeKey(_someKey)) , which will also accept the change.
Believe it or not, Rows.Remove will completely delete the row, while row.Delete() will not. Strike> Note that if you call Rows.Remove , the row will be permanently deleted and will not be deleted from the database using the DataAdapter.

In C # 3, you can replace the if with the following extension method:

 ///<summary>Gets the rows in a typed DataTable that have not been deleted.</summary> public static EnumerableRowCollection<TRow> CurrentRows<TRow>(this TypedTableBase<TRow> table) where TRow : DataRow { return table.Where(r => r.RowState != DataRowState.Deleted); } foreach (myDataTableRow row in _dt.CurrentRows()) { ... 

EDIT

Here is the C # 2 version:

 static class Utils { public static IEnumerable<TRow> CurrentRows(IEnumerable<TRow> table) where TRow : DataRow { foreach(TRow row in table) { if (row.RowState != DataRowState.Deleted) yield return row; } } } foreach (myDataTableRow row in Utils.CurrentRows(_dt)) { 

You can also put this function in an incomplete class for a typed table:

 partial class MyTable { public IEnumerable<MyRow> CurrentRows() { return Utils.CurrentRows(this); } } 
+14
source share

What you do to skip lines in your iteration is correct, I regularly check the RowState when I iterate over a DataTable that can be changed.

In some cases, I believe that you need the original value of the string before the string is marked as deleted. When retrieving a specific datarow value, there is a secondary index option.

 string st = dr["columnname", DataRowVersion.Original].ToString(); // c# dim st As String = dr("columnname", DataRowVersion.Original).ToString() ' vb.net 

I have been stuck with this several times in the past.

Regarding the GetChanges (RowState) method, be sure to check for null returns, if there are no rows for that RowState, the returned DataTable is null (I think it should return a table with null rows)

+2
source share

Use GetChanges ():

 foreach (myDataTableRow row in _dt.GetChanges(DataRowState.Added)) { sbFilter.Append("'" + row.info + "',"); } 

If you want all added and changed, use bitwise OR on added and changed:

 foreach (myDataTableRow row in _dt.GetChanges(DataRowState.Added | DataRowState.Modified)) { sbFilter.Append("'" + row.info + "',"); } 
+1
source share

I'm not sure about this, but I think that if you call _dt.AcceptChanges() after deleting one or more rows, you will not see “deleted rows” when you run the “Collection of rows” data tables again.

0
source share

All Articles