Collection of DataViews

quwiltw

Well-known member
Joined
Sep 18, 2001
Messages
486
Location
Washington, D.C.
I thought there was a collection of dataviews built into the dataset or datatable, but I dont see one now. Am I overlooking something or was it just wishful thinking on my part?

Also, assuming its just not there, anyone see a reason why I shouldnt just give my inherited datasets a strongly typed collection of dataviews? Is there a reason they should be managed separately?
 
Im not sure what you mean by a collection of DataViews...

Each DataTable has a single built-in DataView (accessed through the DefaultView property). You can also create new DataViews from a table by using the following syntax, though the reference is only in the variable - the dataset has no knowledge of the DataView:
C#:
DataView dv = new DataView(datasetvar.Tables["Table1"]);

The only reason Ive had to use DataViews is for binding purposes, where I need multiple views into one table (for sorting or filtering). Ive never needed to keep the DataView around in a collection, but maybe you do. I recently (a few months ago) went back and changed a LOT of code to use the Select method on a DataTable instead of DataViews. I did this in places where I needed to get a value from my DataSet, or a row, but I didnt really need to keep the values around for very long.

For example, if I have a table "Cust" and I need to pull out FirstName and LastName, I could use a DataView or the Select method (which returns a DataRow array). The Select is about twice as fast, and has ALL the same functionality of the DataView (sorting, filtering, selecting from certain DataRowViewStates):
C#:
string firstName;
string lastName;
DataView dv = new DataView(ds.Tables["Cust"], "CustID = 7");
if(dv.Count > 0)
{
    firstName = dv[0]["FirstName"].ToString();
    lastName = dv[0]["LastName"].ToString();
}

DataRow dr = ds.Tables["Cust"].Select("CustID = 7");
if(dr.Length > 0)
{
    firstName = dr[0]["FirstName"].ToString();
    lastName = dr[0]["LastName"].ToString();
}

-Nerseus
 
What I was thinking was if you have a DataTable, it should be able to have a collection of dataviews that are associated with it. So that you can do something like DataTable.Views("MyView"), for example. My thinking is that the DataViews are inseparable from the DataTable, in that, they are useless without it so why not just make them a part of the data table.

Databinding is exactly what Im trying to support with the DataViews. Its essentially a "Lookup" table of stuff like Eye Color, Hair Color, States, Countries, well.. you get the point. Im thinking of bringing them all back in a single data table and just have a DataView for each category. This, because it seems clunky to create a bunch of data tables with the exact same structure.
 
I agree that DataViews are tied to a DataTable and it would be nice to have them referenced through the DataTable as a collection. If your new DataSet class is complete with the DataView collection, maybe you could post it here?

-Nerseus
 
Sorry, I didnt have it, I was asking if it was a bad idea or not;) Heres what Ive got so far though. It appears to work in the little (rather ugly) test methods. The Datatable stuff is first, then there is a class that provides the test method for it.

File: DataTablePlus.vb
Code:
 Class:    DataTablePlus
 Purpose:  
   Extends the DataTable to let it manage associated Views.
Public Class DataTablePlus
    Inherits DataTable

    Private m_objViews As New ViewCollection()

    Public Property Views() As ViewCollection
        Get
            Return m_objViews
        End Get
        Set(ByVal Value As ViewCollection)
            m_objViews = Value
        End Set
    End Property


End Class

 Class:    ViewCollection
 Purpose:  
   A typed collection that contains a set of DataViewPlus objects.
Public Class ViewCollection
    Inherits CollectionBase
    Private m_hshViewNames As New Hashtable()

    Default Public Property Item(ByVal Name As String) As DataViewPlus
        Get
            Return CType(List.Item(DirectCast(m_hshViewNames.Item(Name), Integer)), DataViewPlus)
        End Get
        Set(ByVal Value As DataViewPlus)
            List.Item(DirectCast(m_hshViewNames.Item(Name), Integer)) = Value
        End Set
    End Property

    Default Public Property Item(ByVal Index As Integer) As DataViewPlus
        Get
            Return CType(List.Item(Index), DataViewPlus)
        End Get
        Set(ByVal Value As DataViewPlus)
            List.Item(Index) = Value
        End Set
    End Property

    Public Function Add(ByVal Item As DataViewPlus) As Integer
        Dim i As Integer = List.Add(Item)
        m_hshViewNames.Add(Item.Name, i)
        Return i
    End Function

Protected Overrides Sub OnRemove(ByVal index As Integer, ByVal value As Object)
        Dim en As IDictionaryEnumerator
        Dim sKey As String
        en = m_hshViewNames.GetEnumerator()

        While en.MoveNext
            If CType(en.Value, Integer) = index Then
                sKey = DirectCast(en.Key, String)
            End If
        End While
        m_hshViewNames.Remove(sKey)
    End Sub

End Class


 Class:    DataViewPlus
 Purpose:  
   Adds a Name Property to the DataView.  
Public Class DataViewPlus
    Inherits DataView
    Private m_strName As String

    Public Property Name() As String
        Get
            Return m_strName
        End Get
        Set(ByVal Value As String)
            m_strName = Value
        End Set
    End Property
End Class

DataTest.vb
Code:
Imports System.Text

Public Class DataTest
    Public Sub TestView()
        Dim ds As New DataSet()

        Dim dt As New DataTablePlus()
        ds.Tables.Add(dt)

        dt.Columns.Add(New DataColumn("FirstName"))
        dt.Columns.Add(New DataColumn("LastName"))

        Dim col As ArrayList
        col = GetPeople()
        Dim i As Integer

        For i = 0 To col.Count - 1
            Dim dr As DataRow
            dr = dt.NewRow()
            dr.Item("FirstName") = DirectCast(col.Item(i), Person).FirstName
            dr.Item("LastName") = DirectCast(col.Item(i), Person).LastName
            dt.Rows.Add(dr)
        Next

        Dim vew0 As New DataViewPlus()
        vew0.Name = "All"
        vew0.Table = dt
        vew0.RowFilter = ""
        dt.Views.Add(vew0)

        Dim vew1 As New DataViewPlus()
        vew1.Name = "Georges"
        vew1.Table = dt
        vew1.RowFilter = "FirstName=George"
        dt.Views.Add(vew1)
        Dim vew2 As New DataViewPlus()
        vew2.Name = "Thomases"
        vew2.Table = dt
        vew2.RowFilter = "FirstName=Thomas"
        dt.Views.Add(vew2)

        PrintView(dt.Views.Item("All"))
        PrintView(dt.Views.Item("Georges"))
        PrintView(dt.Views.Item("Thomases"))

    End Sub

    Private Function GetPeople() As ArrayList
        Dim col As New ArrayList()
        col.Add(New Person("John", "Adams"))
        col.Add(New Person("Benjamin", "Franklin"))
        col.Add(New Person("George", "Washington"))
        col.Add(New Person("Thomas", "Jefferson"))
        col.Add(New Person("James", "Madison"))
        col.Add(New Person("Alexander", "Hamilton"))
        col.Add(New Person("George", "Mason"))
        Return col
    End Function

    Private Sub PrintView(ByVal vw As DataViewPlus)
        Dim row As DataRow
        Dim i, n As Integer
        Dim sb As New StringBuilder()


        For i = 0 To vw.Count - 1
            For n = 0 To vw.Table.Columns.Count - 1
                sb.Append(vw.Table.Columns.Item(n).ColumnName)
                sb.Append("=")
                sb.Append(vw.Item(i).Item(n))
                sb.Append(" : ")
            Next
            sb.Append(vbCrLf)

        Next

        MsgBox(sb.ToString())
    End Sub
    Private Class Person
        Public FirstName As String
        Public LastName As String
        Public Sub New(ByVal fname As String, ByVal lname As String)
            FirstName = fname
            LastName = lname
        End Sub
    End Class
End Class

Edit: Ooops wasnt removing from the hashtable too.
 
Last edited by a moderator:
Back
Top