Leaders quwiltw Posted April 11, 2003 Leaders Posted April 11, 2003 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? Quote --tim
*Experts* Nerseus Posted April 11, 2003 *Experts* Posted April 11, 2003 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 Quote "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 quwiltw Posted April 11, 2003 Author Leaders Posted April 11, 2003 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. Quote --tim
*Experts* Nerseus Posted April 11, 2003 *Experts* Posted April 11, 2003 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 Quote "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 quwiltw Posted April 11, 2003 Author Leaders Posted April 11, 2003 (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 April 11, 2003 by quwiltw Quote --tim
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.