Jump to content
Xtreme .Net Talk

Recommended Posts

  • Leaders
Posted

I thought there was a collection of dataviews built into the dataset or datatable, but I don't see one now. Am I overlooking something or was it just wishful thinking on my part?

 

Also, assuming it's just not there, anyone see a reason why I shouldn't just give my inherited datasets a strongly typed collection of dataviews? Is there a reason they should be managed separately?

--tim
  • *Experts*
Posted

I'm 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:

DataView dv = new DataView(datasetvar.Tables["Table1"]);

 

The only reason I've had to use DataViews is for binding purposes, where I need multiple views into one table (for sorting or filtering). I've 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 didn't 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):

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

"I want to stand as close to the edge as I can without going over. Out on the edge you see all the kinds of things you can't see from the center." - Kurt Vonnegut
  • Leaders
Posted

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 I'm trying to support with the DataViews. It's essentially a "Lookup" table of stuff like Eye Color, Hair Color, States, Countries, well.. you get the point. I'm 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.

--tim
  • *Experts*
Posted

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

"I want to stand as close to the edge as I can without going over. Out on the edge you see all the kinds of things you can't see from the center." - Kurt Vonnegut
  • Leaders
Posted (edited)

Sorry, I didn't have it, I was asking if it was a bad idea or not;) Here's what I've 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

' 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

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 wasn't removing from the hashtable too.

Edited by quwiltw
--tim

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...