0

Let's say I have a table with a Color column. Color can have various values. I have a C# method that can handle items of a given column at a time. Thus, I would like to :

foreach(colorname in mytable.getDistinctColornames)
   monocolorMethod(mytable.getSubTableOnlyContainingRowsWithColor(colorname))

How would I do that elegantly ... ?

At all prices, I would avoid copying the data back & forth. I would like kind of a view on the datatable. A view that would only "show" the rows of a given columns, and a "writable" view (i.e. when I write to the filtered subset, the original table is written to)

EDIT :

Let's say I have a 'Car' Table, and I would like to replace 'Sedan' by 'Truck' in column 'Type' for all cars with 'Color=Red'.

How would I do given the following code ?

DataTable cars (...); // the data

DataView dv = cars.DefaultView;
dv.RowFilter = "Color='Red'";

< Here I would like to loop on the DataView>. The following code does not work :

foreach (row in dv.AsEnumerable)
{
  if(row["Type"] == "Sedan")
    row["Type"] = "Truck";
}

EDIT 2 :

Found this http://msdn.microsoft.com/fr-fr/library/system.data.dataview.allowedit.aspx which suggests

view.AllowEdit = true;
view[0].BeginEdit();
view[0]["FirstName"] = "Mary";
view[0]["LastName"] = "Jones";
view[0].EndEdit();
madth3
  • 7,275
  • 12
  • 50
  • 74
Skippy Fastol
  • 1,745
  • 2
  • 17
  • 32

2 Answers2

2

Check out this:

Querying DataSets – Introduction to LINQ to DataSet

alexm
  • 6,854
  • 20
  • 24
1

Did you try using DataView class? It looks like exactly what you want to achieve without using LINQ: http://msdn.microsoft.com/en-us/library/fdcwwhez

An example of usage:

Let say there is a DataTable object named _dt with 4 rows in it:

_dt = new DataTable("") {Columns = {new DataColumn("ID"), new DataColumn("Name"), new DataColumn("Order")}};
_dt.Rows.Add(1, "one", 1);
_dt.Rows.Add(2, "two", 3);
_dt.Rows.Add(3, "three", 2);
_dt.Rows.Add(4, "four", 5);

You can easily create DataView which doesn't filter data but perform sorting operation on it:

_dv = new DataView(_dt, "", "Order, Name", DataViewRowState.CurrentRows);

You can also add new rows into the DataView and because it is set on corresponding DataTable that new row will be added directly to _dt object. The sorting order will be updated as well, and new row won't be the last one within the DataView (because sort is done on Order and Name columns)

var newRow = _dv.AddNew();
newRow["ID"] = 5;
newRow["Name"] = "five";
newRow["Order"] = 4;
newRow.EndEdit();

After that code there will be 5 rows in _dt. Editing rows is also quite simple:

var editedRow = _dv[0];
editedRow.BeginEdit();
editedRow["Name"] = "Test";
editedRow.EndEdit();

You can also use DataView.Find() or DataView.FindRows() methods to find a row within the DataView.

MarcinJuraszek
  • 124,003
  • 15
  • 196
  • 263
  • could you please give an example ? Let's say I'd want my view to be the table itself, but sorted by a first column, then a second one (equivalent to OrderBy(A).ThenBy(B)). Will the writes to the DataView be automatically performed on the original table ? – Skippy Fastol Jul 05 '12 at 13:07
  • I've updated my answer. Hope that example will help you with your problem. – MarcinJuraszek Jul 05 '12 at 14:55
  • Just wondering : how do you actually browse the DataView to edit the values of some of its rows (and thus, of the original DataTable) – Skippy Fastol Jul 05 '12 at 14:58
  • You don't have to modify the data through the `DataView`. You can easily modify it by `DataTable`, and the view would be updated as well. – MarcinJuraszek Jul 05 '12 at 15:03
  • Let's say that the algorithm I use needs to browse the *Datatable* in a given order (e.g. with increasing IDs). I thought I could write to the *DataView*, sorted by ID. Does that make sense ? – Skippy Fastol Jul 05 '12 at 15:08
  • then my problem is precisely to know how to write to _dv (as opposed to _dt) – Skippy Fastol Jul 05 '12 at 15:29
  • Example for adding new rows is already in my answer. I also updated it with an edit example. – MarcinJuraszek Jul 05 '12 at 15:38