# Visual Basic > Visual Basic .NET >  [RESOLVED] Sub-Filtering a Dataview

## Shaggy Hiker

I have a problem that I solved by taking a round trip to a DB, but I'm wondering if there might not be something I'm overlooking. 

I have a datatable that holds a bunch of stuff. From this, I take a Dataview and filter it. The user will only see that filtered DV, though the underlying DT will normally hold a fair amount more.

There are half a dozen fields in the DV. Of those fields, there are two that are likely to have repeats in them. What I need to get is the ordered set of unique values from each of those fields. Basically, it is the same problem twice. One field holds dates, the other strings, but the data type shouldn't much matter.

So, the core problem is: For a single field in a Dataview (but not the underlying table), get the set of unique values into a List.

I didn't bother with this, as going back to the DB and getting this list via a simple query is going to be easily fast enough. It might be better, too, in this case, for reasons I won't get into. Even a single line solution is probably worse, but I'm wondering whether or not there is one.

----------


## jmcilhinney

You can do a LINQ query on a DataView - each item is a DataRowView - so you can do something like this:

vb.net Code:
Dim values = myDataView.Cast(Of DataRowView)().
                        Select(Function(drv) CStr(drv("SomeColumn"))).
                        Distinct()
You can also call ToTable on a DataView to create a new DataTable based on the data in the view, even removing certain columns if desired, and then use it like you would any other DataTable.

----------


## Shaggy Hiker

That's what I was looking for. I might even use it. Still testing performance, though, and this isn't looking like the bottleneck.

----------


## vbdotnut

I think you would find the ToTable method to be quicker, though Ive been wrong before. If I am reading you right maybe this?


```
Dim YourDT As New DataTable
'Do Filter
YourDT.DefaultView.RowFilter = "..."
For Each DTCol As DataColumn In YourDT.Columns
    Select Case DTCol.ColumnName
        Case "Col1", "Col2", "Etc..."
            Dim DVasDT As DataTable = YourDT.DefaultView.ToTable(True, DTCol.ColumnName)

            'Could sort here, maybe faster to sort resulting arrays tho
            DVasDT.DefaultView.Sort = DTCol.ColumnName & " ASC"
            'Put result in array, could also get array of string from values
            Dim UniqueRows As DataRow() = DVasDT.Select(DTCol.ColumnName & " IS NOT NULL")
            If UniqueRows.Count > 0 Then

            End If
    End Select
Next
```

Looking at this again, the sort wouldnt be preserved unless you were to get yet another table from the DefaultView of DVasDT, so you would need to play with that

----------


## Shaggy Hiker

I wasn't aware of the overload of ToTable. That does look pretty useful. I'll have to play around with that.


I'm curious as to why you are selecting for IS NOT NULL. It doesn't seem to offer much of a benefit.

----------


## vbdotnut

> I'm curious as to why you are selecting for IS NOT NULL. It doesn't seem to offer much of a benefit.


If there is a null value in the data the Distinct parameter (first param in ToTable method) will include it as a value. If it is not possible for a NULL to exist, or you want a null value in the result otherwise, you could drop that clause

----------


## Shaggy Hiker

Yeah, I'd want the Null in there if it was there, but there won't be any, so I guess it doesn't really matter.

----------


## vbdotnut

I had a thought about this, wondering if we've overcomplicated the situation. I think it would be faster and less typing to iterate the dataview.ToTable.Rows and add them to a list, or a dictionary if value is not found.

----------


## Shaggy Hiker

Yeah, that route is always possible. It would likely perform slightly better, as well, but I could also fill the list with a direct query from the DB, so I was really looking for alternatives. I got those.

----------

