0

I need to eliminate all rows that contain either string notUsed or string notUsed2, where a particular identity is 2.

I'm using a foreach loop to accomplish this, prior to appending any of my data to a stringbuilder.

I would have chosen a method like so:

foreach (DataRow dr in ds.Tables[0].Rows)
    {
        int auth = (int)dr[0];
        if (auth == 2) continue;
        string notUsed = "NO LONGER USED";
        string notUsed2 = "NO LONGER IN USE";

        if (dr.Cells[3].ToString().Contains(string)notUsed)
        {
            dr.Delete();
        }
        else
        {
            if (dr.Cells[3].ToString().Contains(string)notUsed2)
            {
                dr.Delete();
            }
        }
    }

However, the above is... utterly wrong. It seems logical to me, but I don't quite understand how to form that method in a way that C# understands.

Wolfish
  • 960
  • 2
  • 8
  • 34
  • 2
    Just remove `string` from Contains like: `if (dr[3].ToString().Contains(notUsed))`. Also you are trying to modify the collection in a `foreach` loop by deleting the rows. It will raise the exception. Use a `for` loop, better if you use it in reverse order – Habib Sep 05 '14 at 13:54
  • @Habib but what do I use in place of `Cells` ? – Wolfish Sep 05 '14 at 13:56
  • 1
    just remove `Cells` it should be `dr[3]` – Habib Sep 05 '14 at 13:59

1 Answers1

1

You should

  • Remove Cells as it is not a property of DataRow instead use dr[3].
  • Remove string from Contains so your check should be like: if (dr[3].ToString().Contains(notUsed))
  • You are modifying the collection inside a foreach loop, by deleting the row. You should use for loop backward.

Like:

for (int i = ds.Tables[0].Rows.Count - 1; i >= 0; i--)
{
    DataRow dr = ds.Tables[0].Rows[i];
    int auth = (int)dr[0];
    if (auth == 2) continue;
    string notUsed = "NO LONGER USED";
    string notUsed2 = "NO LONGER IN USE";

    if (dr[3].ToString().Contains(notUsed))
    {
        dr.Delete();
    }
    else
    {
        if (dr[3].ToString().Contains(notUsed2))
        {
            dr.Delete();
        }
    }
}

You can also use LINQ to DataSet and get a new DataTable like:

DataTable newDataTAble = ds.Tables[0].AsEnumerable()
                            .Where(r => !r.Field<string>(3).Contains(notUsed) &&
                                        r.Field<string>(3).Contains(notUsed2))
                            .CopyToDataTable();
Habib
  • 219,104
  • 29
  • 407
  • 436