JamesFaix
JamesFaix

Reputation: 8655

C# create DataView from DataView

I would like to create a new DataView by filtering an existing DataView, however I'm having trouble since DataView does not have a .AsEnumerable() method and does not implement IEnumerable{DataRow}.

Here is basically what I want to accomplish:

//Some table.
DataTable dt = new DataTable();

//Somewhere in here the table is given columns and rows...

//The first view shows some subset of the table.  
//(This works fine.)
DataView dv1 = dt.AsEnumerable()
    .Where(r => r.Field<int>("ID") < 1000)
    .AsDataView();

//The second view should show a subset of the first view, but I cannot find the methods to do this.
//(This does not compile.)
DataView dv2 = dv1.AsEnumerable()
    .Where(r => r.Field<int>("Salary") > 50000)
    .AsDataView();

The best thing I've come up with so far is

DataView dv2 = dv1.ToDataTable().AsEnumerable()
   .Where(r => r.Field<int>("Salary") > 50000)
   .AsDataView();

which is ugly and I'm guessing inefficient.

What's the best way to make a view from a view?

Upvotes: 2

Views: 1117

Answers (2)

Naeem Akhtar
Naeem Akhtar

Reputation: 1

Create the first DataTable than add column than add and modified the data. after applying DataViewRowState filtering get first DataView, Than delete few recodes get 2nd DataView:

        DataTable dataTable = new DataTable("dataTable");
        DataColumn dataColumn = new DataColumn("dataColumn");
        dataTable.Columns.Add(dataColumn);
        DataRow dataRow;

        for (int i = 0; i <= 10 - 1; i++)
        {
            dataRow = dataTable.NewRow();
            dataRow["dataColumn"] = "item " + i;
            dataTable.Rows.Add(dataRow);
        }

        dataTable.AcceptChanges();
        DataView dataView = new DataView(dataTable);

        dataView = dataTable.DefaultView;


        dataTable.Rows[1]["dataColumn"] = "Hello";
        dataRow = dataTable.NewRow();
        dataRow["dataColumn"] = "World";
        dataTable.Rows.Add(dataRow);
        dataView.RowStateFilter = DataViewRowState.Added | DataViewRowState.ModifiedCurrent;
        
        DataView dataView1 = dataView.ToTable().DefaultView; //1st View

        dataView.RowStateFilter = DataViewRowState.ModifiedOriginal;
        dataTable.Rows[1].Delete();
        dataTable.Rows[2].Delete();
        dataTable.Rows[3].Delete();
        dataView.RowStateFilter = DataViewRowState.Deleted;

        DataView dataView2 = dataView.ToTable().DefaultView; //2nd View

Upvotes: 0

manji
manji

Reputation: 47978

Create the first filter in a separate IEnumerable, then use it to create both dataviews:

var filtered = dt.AsEnumerable()
                 .Where(r => r.Field<int>("ID") < 1000);


DataView dv1 = filtered.AsDataView();

DataView dv2 = filtered.Where(r => r.Field<string>("Salary") > 50000)
                       .AsDataView();

Upvotes: 2

Related Questions