1

I have a DataSet dsComponents that embraces many tables, all of them are only in-memory, I don't sync them with any database. At some moments I need to remove all rows to free some memory but the function seems not to working (based on this answer)

if(dsComponents.Tables.Contains("MemoryHistory"))
{
  dsComponents.Tables["MemoryHistory"].Rows.Clear();
}

But if I break right after this code it shows that there still all rows in the table. I also tried:

if(dsComponents.Tables.Contains("MemoryHistory"))
{
  lock(dsComponents.Tables["MemoryHistory"])
  {
    foreach (DataRow row in dsComponents.Tables["MemoryHistory"].Rows)
    {
      row.Delete();
    }
  }
  dsComponents.Tables["MemoryHistory"].Rows.Clear();
}

and this one fails with "Collection was modified; enumeration operation may not execute", even with the lock. So, how to clear the rows of the table but preserve the table itself (like its Primary key, etc...)?

4
  • dsComponents.Tables["MemoryHistory"].Rows.Clear() should work properly. Are you sure it's hitting that line of code and nothing else is interfering with it?
    – jtate
    Commented Oct 1, 2018 at 18:49
  • yep, at least according to VS debugger it is hitting. I also break right after to check it the rows were cleared
    – Fnr
    Commented Oct 1, 2018 at 18:50
  • 1
    you can't use a foreach loop and then add/remove elements to the collection inside the loop, so you could try an old fashioned for loop but go backwards, for (int i = dsComponents.Tables["MemoryHistory"].Rows.Count - 1; i >= 0; i--) and then call dsComponents.Tables["MemoryHistory"].Rows[i].Delete() inside the loop
    – jtate
    Commented Oct 1, 2018 at 19:01
  • @jtate this worked, thanks
    – Fnr
    Commented Oct 1, 2018 at 19:14

2 Answers 2

3

The issue here is that your are modifying an Enumerable as you are iterating over it which is not allowed.

You need to reset the rows property on the table without iterating over the rows.

Think about like iterating over a List<T>

You would not do

foreach (var element in list)
{
    list.Remove(element);
}

Instead you would do something like:

list.Clear();

In your case you would want to do

dsComponents.Tables["MemoryHistory"].Rows.Clear();

I am not sure of your need for the lock object, but if you clarify that, I would be happy to modify my answer.

1

Just do

dsComponents.Tables["MemoryHistory"].Clear();
2
  • this will also wipe the primary key of the table. I dont want to redefine the constraints again...
    – Fnr
    Commented Oct 1, 2018 at 18:46
  • Have you tried dsComponents.Tables["MemoryHistory"] = dsComponents.Tables["MemoryHistory"].Clone(); ?
    – Frank Ball
    Commented Oct 1, 2018 at 19:03

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.