HOW TO: Implement a DataSet SELECT DISTINCT Helper Class in Visual Basic .NET (325684)
The information in this article applies to:
- Microsoft ADO.NET (included with the .NET Framework 1.1)
- Microsoft ADO.NET (included with the .NET Framework) 1.0
- Microsoft Visual Basic .NET (2003)
- Microsoft Visual Basic .NET (2002)
This article was previously published under Q325684 For a Microsoft Visual C# .NET version of
this article, see
326176 HOW TO: Implement a DataSet JOIN helper class in Visual C# .NET
NOTE: This article is one of a series of DataSetHelper articles. You can merge the code in the DataSetHelper class that is listed in this article with the code that is
provided in other DataSetHelper articles to make a single class with a more comprehensive feature
set. This article refers to the following Microsoft .NET Framework
Class Library namespace:
IN THIS TASKSUMMARY This step-by-step article illustrates how to implement and
how to use a DataSetHelper class that includes sample code to create a DataTable object that contains the unique values of a column of another DataTable object. To do this, you use the SelectDistinct public method. You can also use a private helper method that
compares fields that may contain NULL values (DBNull.Value). The DataSetHelper class includes a DataSet member variable. Optionally, you can assign an existing DataSet object to the DataSet member variable. If the member variable points to a valid DataSet, any DataTable objects that the SelectDistinct method creates are added to the DataSet. In either case, the method call returns a reference to the DataTable object. For additional information about DataSet objects, click the article number below to view the article in
the Microsoft Knowledge Base:
313485 INFO: Roadmap for ADO.NET DataSet, DataView, and DataViewManager Objects
back to the top
Requirements The following list outlines the recommended hardware, software,
network infrastructure, and service packs that are required:
- Microsoft Windows XP, Windows 2000, or Windows NT 4.0
Service Pack 6a
- Microsoft Visual Studio .NET
This article assumes that you are familiar with the following
topics:
- Visual Basic .NET syntax
- ADO.NET fundamentals and syntax
back to the top
DataSetHelper Shell Class The code in this section declares the shell class to which all DataSetHelper articles add methods and member variables.
- Start Visual Studio .NET.
- On the File menu, point to New, and then click Project.
- In the New Project dialog box, click Visual Basic Projects under Project Types, and then click Class Library under Templates.
- In the Name box, type DataSetHelper.
- Replace the class code with the following code:
Public Class DataSetHelper
Public ds As DataSet
Public Sub New(ByVal DataSet As DataSet)
ds = DataSet
End Sub
Public Sub New()
ds = Nothing
End Sub
End Class
You can use the two overloads for the constructor to create an instance
of the class with or without a reference to a valid DataSet. For a class that contains a reference to a valid DataSet, the DataTable objects that the methods return are also added automatically to
the DataSet.
back to the top
SelectDistinct Method This section contains the code for the SelectDistinct method and the private ColumnEqual helper method.
- Add the following Private method to the class definition. This method is the same as the
method that is used in other DataSetHelper articles and is used to compare field values (including NULL).
Private Function ColumnEqual(ByVal A As Object, ByVal B As Object) As Boolean
'
' Compares two values to determine if they are equal. Also compares DBNULL.Value.
'
' NOTE: If your DataTable contains object fields, you must extend this
' function to handle the fields in a meaningful way if you intend to group on them.
'
If A Is DBNull.Value And B Is DBNull.Value Then Return True ' Both are DBNull.Value.
If A Is DBNull.Value Or B Is DBNull.Value Then Return False ' Only one is DBNull.Value.
Return A = B ' Value type standard comparison
End Function
- Add the following Public method to the class definition. This method copies unique values
of the field that you select into a new DataTable. If the field contains NULL values, a record in the destination
table will also contain NULL values.
Public Function SelectDistinct(ByVal TableName As String, _
ByVal SourceTable As DataTable, _
ByVal FieldName As String) As DataTable
Dim dt As New DataTable(TableName)
dt.Columns.Add(FieldName, SourceTable.Columns(FieldName).DataType)
Dim dr As DataRow, LastValue As Object
For Each dr In SourceTable.Select("", FieldName)
If LastValue Is Nothing OrElse Not ColumnEqual(LastValue, dr(FieldName)) Then
LastValue = dr(FieldName)
dt.Rows.Add(New Object() {LastValue})
End If
Next
If Not ds Is Nothing Then ds.Tables.Add(dt)
Return dt
End Function
back to the top
Test the Application- Save and then compile the DataSetHelper class that you created in the previous sections.
- Follow these steps to create a new Visual Basic Windows
Application:
- Start Visual Studio .NET.
- On the File menu, point to New, and then click Project.
- In the New Project dialog box, click Visual Basic Projects under Project Types, and then click Windows Application under Templates.
- In Solution Explorer, right-click the solution, and then
click Add Existing Project. Add the DataSetHelper project.
- On the Project menu, click Add Reference.
- In the Add Reference dialog box, click the Projects tab, and then add a reference to the DataSetHelper project to the
Windows Form application.
- In the form designer, drag a Button control and a DataGrid control from the toolbox to the form. Name the button
btnSelectDistinct, and then keep the default name for
the DataGrid control (DataGrid1).
- In the form code, add the following Imports statement to the top of the Code window:
Imports System.Data
- Add the following variable declarations to the form
definition:
Dim ds As DataSet, dsHelper As DataSetHelper.DataSetHelper
- Add the following code to the Form.Load event:
ds = New DataSet()
dsHelper = New DataSetHelper.DataSetHelper(ds)
'
' Create source table
'
Dim dt As New DataTable("Orders")
dt.Columns.Add("EmployeeID", GetType(String))
dt.Columns.Add("OrderID", GetType(Integer))
dt.Columns.Add("Amount", GetType(Decimal))
dt.Rows.Add(New Object() {"Sam", 5, 25.00})
dt.Rows.Add(New Object() {"Tom", 7, 50.00})
dt.Rows.Add(New Object() {"Sue", 9, 11.00})
dt.Rows.Add(New Object() {"Tom", 12, 7.00})
dt.Rows.Add(New Object() {"Sam", 14, 512.00})
dt.Rows.Add(New Object() {"Sue", 15, 17.00})
dt.Rows.Add(New Object() {"Sue", 22, 2.50})
dt.Rows.Add(New Object() {"Tom", 24, 3.00})
dt.Rows.Add(New Object() {"Tom", 33, 78.75})
ds.Tables.Add(dt)
- Add the following code to the btnSelectDistinct.Click event:
dsHelper.SelectDistinct("DistinctEmployees", ds.Tables!Orders, "EmployeeID")
DataGrid1.SetDataBinding(ds, "DistinctEmployees")
- Run the application, and then click the button one time.
Notice that the DataGrid is populated with the tables and the data from the
code.
NOTE: You can only click the btnSelectDistinct button one time. If you click the button more than one time, you
receive an error message that you are trying to add the same table two
times.
back to the top
Enhancement Ideas You can only use the function to select a single, distinct field.
However, you can extend the functionality to include multiple fields.
Alternatively, you can call the CreateGroupByTable, the InsertGroupByInto, and the SelectGroupByInto methods, which use GROUP BY-type functionality, to get the same
kind of results.
back to the top
Troubleshooting- The fieldname and the alias parts of the field list must
comply with DataColumn naming conventions. The parser also restricts the names, in that
the name must not contain a period (.), a comma (,), or a space ( ).
- If you click the button more than one time, the same table
is added two times to the DataSet, which results in an exception. To work around this problem, you
can add code to the test application to check whether a DataTable of the same name already exists. Alternatively, you can create
the DataSetHelper class without a reference to a DataSet and then bind the DataGrid.DataSource property directly to the dt variable instead of by using the SetDataBinding method call.
- If the source table uses custom data types (that is, a
class), you must add code to the SelectDistinct method to perform a deep copy of the data. Otherwise, only a
reference is copied.
back to the top
Modification Type: | Major | Last Reviewed: | 9/23/2003 |
---|
Keywords: | kbHOWTOmaster kbSystemData KB325684 kbAudDeveloper |
---|
|