deleting row from dataset

T

tshad

I have a dataset I am trying to delete all datarows from except for ones
that match some type of criteria.

I tried:

foreach (DataRow dr in AppSettings.ds.Tables["form"].Rows)
{
if ((string)dr["tagName"] != "CITY.1")
{
dr.Delete();
}
}

But get an error:

Collection was modified; enumeration operation might not execute.

How else would I do this?

Thanks,

Tom
 
M

Martin Honnen

tshad said:
I tried:

foreach (DataRow dr in AppSettings.ds.Tables["form"].Rows)
{
if ((string)dr["tagName"] != "CITY.1")
{
dr.Delete();
}
}

But get an error:

Collection was modified; enumeration operation might not execute.

How else would I do this?

DataTable table = AppSettings.ds.Tables["form"];
for (int i = table.Rows.Count - 1; i >= 0; i--)
{
DataRow row = table.Rows;
if ((string)row["tagName"] != "CITY.1")
{
row.Delete();
}
}
 
T

tshad

Martin Honnen said:
tshad said:
I tried:

foreach (DataRow dr in
AppSettings.ds.Tables["form"].Rows)
{
if ((string)dr["tagName"] != "CITY.1")
{
dr.Delete();
}
}

But get an error:

Collection was modified; enumeration operation might not execute.

How else would I do this?

DataTable table = AppSettings.ds.Tables["form"];
for (int i = table.Rows.Count - 1; i >= 0; i--)
{
DataRow row = table.Rows;
if ((string)row["tagName"] != "CITY.1")
{
row.Delete();
}
}


Would my deleting a row change row that the index is pointing ?

For example, if I deleted row 10, would row 11 now be pointing at the old
row 12? This would be a problem since I would miss checking the old row 11
for my criteria.

I did also try cloning the table and move the data that way:

DataTable dt = new DataTable();
dt = AppSettings.ds.Tables["form"].Clone();

foreach (DataRow dr in AppSettings.ds.Tables["form"].Rows)
{
if ((string)dr["tagName"] == "CITY.1")
{
dt.ImportRow(dr);
}
}
AppSettings.ds.Tables.Remove(AppSettings.ds.Tables["form"]);

This seems to work, but how would I move the new datatable (dt) into the
dataset.

Also, is there a way to move the datatable in Table Position 0? This is not
necessary as I access the table by name but curious if I can.

This is needed as I am adjusting the datatable to run it through some
existing code that expects a dataset.

Thanks,

Tom
 
V

vanderghast

Would my deleting a row change row that the index is pointing ?
For example, if I deleted row 10, would row 11 now be pointing at the old
row 12? This would be a problem since I would miss checking the old row
11 for my criteria.


No, not even for standard list: when you start at index N, toward 1, so
deleting M, won't make you miss any record below since the next loop
execution will look for M-1, the element below it.

Note that HERE, it is very unlikely that you effectively DELETE anything!
Indedd, it is quite probably that you ONLY mark the row state as deleted,
nothing more, AND when you will synchronize back the row, ADO Net will read
that data, see its status as deleted, and will THEN try to delete it IN THE
DATABASE, and finally, ONLY AFTER THAT, would it be deleted it from your
side. BUT only after a resychronisation, NOT immediatly: If it was to
simply delete it, from your side, BEFORE making any synchronization with the
database, how would ADO Net be aware of that it has to delete it!
Furthermore, yconsider that ou can still filter / see deleted stuff (as long
as you don't resynch), with the overload indexer: dr[fieldName,
DataRowVersion ].

Furthermore, if ever you re-execute again your loop after a first "delete"
pass, BEFORE you resynchronize it with the database, you will likely get an
error trying to read a field from a row marked as deleted! So, *if* this is
a possibility, check the rowState before: trying to read the field:

if ( dr.RowState != DataRowState.Deleted && (string)dr["tagName"] !=
"CITY.1")
{
...
}


Sure, that extra test is not necessary if you resych your data immediatly
after this loop.


I am clueless about why foreach does not allow the delete(), since it
deletes nothing (if my point of view is correct). Sure, standard foreach do
not allow standard delete, so, maybe it is more "by design" for uniformity,
than for real need. I can be wrong, though, have never seen the IL code
behind that delete(), neither the one behind foreach, by the way.




Vanderghast, Access MVP


tshad said:
Martin Honnen said:
tshad said:
I tried:

foreach (DataRow dr in
AppSettings.ds.Tables["form"].Rows)
{
if ((string)dr["tagName"] != "CITY.1")
{
dr.Delete();
}
}

But get an error:

Collection was modified; enumeration operation might not execute.

How else would I do this?

DataTable table = AppSettings.ds.Tables["form"];
for (int i = table.Rows.Count - 1; i >= 0; i--)
{
DataRow row = table.Rows;
if ((string)row["tagName"] != "CITY.1")
{
row.Delete();
}
}


Would my deleting a row change row that the index is pointing ?

For example, if I deleted row 10, would row 11 now be pointing at the old
row 12? This would be a problem since I would miss checking the old row
11 for my criteria.

I did also try cloning the table and move the data that way:

DataTable dt = new DataTable();
dt = AppSettings.ds.Tables["form"].Clone();

foreach (DataRow dr in AppSettings.ds.Tables["form"].Rows)
{
if ((string)dr["tagName"] == "CITY.1")
{
dt.ImportRow(dr);
}
}

AppSettings.ds.Tables.Remove(AppSettings.ds.Tables["form"]);

This seems to work, but how would I move the new datatable (dt) into the
dataset.

Also, is there a way to move the datatable in Table Position 0? This is
not necessary as I access the table by name but curious if I can.

This is needed as I am adjusting the datatable to run it through some
existing code that expects a dataset.

Thanks,

Tom
 
T

tshad

Mark Rae said:
Ordinarily, yes, but that's why Martin's code starts at the end and works
backwards...
for (int i = table.Rows.Count - 1; i >= 0; i--)
That makes sense.

I didn't notice it was doing that.

Thanks,

Tom
 
T

tshad

vanderghast said:
Would my deleting a row change row that the index is pointing ?

For example, if I deleted row 10, would row 11 now be pointing at the old
row 12? This would be a problem since I would miss checking the old row
11 for my criteria.


No, not even for standard list: when you start at index N, toward 1, so
deleting M, won't make you miss any record below since the next loop
execution will look for M-1, the element below it.

Note that HERE, it is very unlikely that you effectively DELETE anything!
Indedd, it is quite probably that you ONLY mark the row state as deleted,
nothing more, AND when you will synchronize back the row, ADO Net will
read that data, see its status as deleted, and will THEN try to delete it
IN THE DATABASE, and finally, ONLY AFTER THAT, would it be deleted it
from your side. BUT only after a resychronisation, NOT immediatly: If it
was to simply delete it, from your side, BEFORE making any synchronization
with the database, how would ADO Net be aware of that it has to delete it!
Furthermore, yconsider that ou can still filter / see deleted stuff (as
long as you don't resynch), with the overload indexer: dr[fieldName,
DataRowVersion ].
If that is the case, this would be pointless to do at all.

I am not using this to update the database but to limit the records I am
looking at.

My code goes through the DataTable and uses each row. This is why I am
trying to get rid the row.

If the code works this way, then I will have to use the other approach which
is to move the fields I want to process to another datatable, remove the old
table and add this table into the dataset.

I did figure out how to add the new table into the dataset, BTW.

AppSettings.ds.Tables.Add(dt

Thanks,

Tom
Furthermore, if ever you re-execute again your loop after a first "delete"
pass, BEFORE you resynchronize it with the database, you will likely get
an error trying to read a field from a row marked as deleted! So, *if*
this is a possibility, check the rowState before: trying to read the
field:

if ( dr.RowState != DataRowState.Deleted && (string)dr["tagName"] !=
"CITY.1")
{
...
}


Sure, that extra test is not necessary if you resych your data immediatly
after this loop.


I am clueless about why foreach does not allow the delete(), since it
deletes nothing (if my point of view is correct). Sure, standard foreach
do not allow standard delete, so, maybe it is more "by design" for
uniformity, than for real need. I can be wrong, though, have never seen
the IL code behind that delete(), neither the one behind foreach, by the
way.




Vanderghast, Access MVP


tshad said:
Martin Honnen said:
tshad wrote:

I tried:

foreach (DataRow dr in
AppSettings.ds.Tables["form"].Rows)
{
if ((string)dr["tagName"] != "CITY.1")
{
dr.Delete();
}
}

But get an error:

Collection was modified; enumeration operation might not execute.

How else would I do this?

DataTable table = AppSettings.ds.Tables["form"];
for (int i = table.Rows.Count - 1; i >= 0; i--)
{
DataRow row = table.Rows;
if ((string)row["tagName"] != "CITY.1")
{
row.Delete();
}
}


Would my deleting a row change row that the index is pointing ?

For example, if I deleted row 10, would row 11 now be pointing at the old
row 12? This would be a problem since I would miss checking the old row
11 for my criteria.

I did also try cloning the table and move the data that way:

DataTable dt = new DataTable();
dt = AppSettings.ds.Tables["form"].Clone();

foreach (DataRow dr in AppSettings.ds.Tables["form"].Rows)
{
if ((string)dr["tagName"] == "CITY.1")
{
dt.ImportRow(dr);
}
}

AppSettings.ds.Tables.Remove(AppSettings.ds.Tables["form"]);

This seems to work, but how would I move the new datatable (dt) into the
dataset.

Also, is there a way to move the datatable in Table Position 0? This is
not necessary as I access the table by name but curious if I can.

This is needed as I am adjusting the datatable to run it through some
existing code that expects a dataset.

Thanks,

Tom
 
C

Cor Ligthert[MVP]

thad,

There is in the system.Data namespace a fine difference between "remove" and
"delete"

"Delete" marks and "Remove" removes.

Therefore use one of the remove methods as you do not use any database
update or worse use the acceptchanges everytime you delete something.
(You can then not use anymore the dataset to update a database)

Cor

tshad said:
Mark Rae said:

Not really, as the code that is in production doesn't look at the default
view and I can't really change that.

Thanks,

tom
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top