Share via


Energize Your Data Retrieval Code with ADO.NET Objects—Sample 1

 

Imports System.Data
Imports System.Data.SqlClient
Imports System.Text


Public Class Form1
    Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "

    Public Sub New()
        MyBase.New()

        'This call is required by the Windows Form Designer.
        InitializeComponent()

        'Add any initialization after the InitializeComponent() call

    End Sub

    'Form overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    Friend WithEvents DataGrid1 As System.Windows.Forms.DataGrid
    Friend WithEvents Button1 As System.Windows.Forms.Button
    Friend WithEvents Button2 As System.Windows.Forms.Button
    Friend WithEvents StatusBar1 As System.Windows.Forms.StatusBar
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.DataGrid1 = New System.Windows.Forms.DataGrid()
        Me.Button1 = New System.Windows.Forms.Button()
        Me.Button2 = New System.Windows.Forms.Button()
        Me.StatusBar1 = New System.Windows.Forms.StatusBar()
        CType(Me.DataGrid1, System.ComponentModel.ISupportInitialize).BeginInit()
        Me.SuspendLayout()
        '
        'DataGrid1
        '
        Me.DataGrid1.AllowNavigation = False
        Me.DataGrid1.AlternatingBackColor = System.Drawing.Color.LightGray
        Me.DataGrid1.Anchor = (((System.Windows.Forms.AnchorStyles.Top _
          Or System.Windows.Forms.AnchorStyles.Bottom) _
                    Or System.Windows.Forms.AnchorStyles.Left) _
                    Or System.Windows.Forms.AnchorStyles.Right)
        Me.DataGrid1.BackColor = System.Drawing.Color.Gainsboro
        Me.DataGrid1.BackgroundColor = System.Drawing.Color.Silver
        Me.DataGrid1.BorderStyle = System.Windows.Forms.BorderStyle.None
        Me.DataGrid1.CaptionBackColor = System.Drawing.Color.LightSteelBlue
        Me.DataGrid1.CaptionForeColor = System.Drawing.Color.MidnightBlue
        Me.DataGrid1.DataMember = ""
        Me.DataGrid1.FlatMode = True
        Me.DataGrid1.Font = New System.Drawing.Font("Tahoma", 8.0!)
        Me.DataGrid1.ForeColor = System.Drawing.Color.Black
        Me.DataGrid1.GridLineColor = System.Drawing.Color.DimGray
        Me.DataGrid1.GridLineStyle = System.Windows.Forms.DataGridLineStyle.None
        Me.DataGrid1.HeaderBackColor = System.Drawing.Color.MidnightBlue
        Me.DataGrid1.HeaderFont = New System.Drawing.Font("Tahoma", _
          8.0!, System.Drawing.FontStyle.Bold)
        Me.DataGrid1.HeaderForeColor = System.Drawing.Color.White
        Me.DataGrid1.LinkColor = System.Drawing.Color.MidnightBlue
        Me.DataGrid1.Location = New System.Drawing.Point(8, 32)
        Me.DataGrid1.Name = "DataGrid1"
        Me.DataGrid1.ParentRowsBackColor = System.Drawing.Color.DarkGray
        Me.DataGrid1.ParentRowsForeColor = System.Drawing.Color.Black
        Me.DataGrid1.ReadOnly = True
        Me.DataGrid1.SelectionBackColor = System.Drawing.Color.CadetBlue
        Me.DataGrid1.SelectionForeColor = System.Drawing.Color.White
        Me.DataGrid1.Size = New System.Drawing.Size(728, 288)
        Me.DataGrid1.TabIndex = 0
        '
        'Button1
        '
        Me.Button1.Location = New System.Drawing.Point(360, 8)
        Me.Button1.Name = "Button1"
        Me.Button1.Size = New System.Drawing.Size(184, 24)
        Me.Button1.TabIndex = 1
        Me.Button1.Text = "Run distinct queries..."
        '
        'Button2
        '
        Me.Button2.Location = New System.Drawing.Point(552, 8)
        Me.Button2.Name = "Button2"
        Me.Button2.Size = New System.Drawing.Size(184, 24)
        Me.Button2.TabIndex = 2
        Me.Button2.Text = "Run single query and splits..."
        '
        'StatusBar1
        '
        Me.StatusBar1.Location = New System.Drawing.Point(0, 303)
        Me.StatusBar1.Name = "StatusBar1"
        Me.StatusBar1.Size = New System.Drawing.Size(744, 22)
        Me.StatusBar1.TabIndex = 3
        '
        'Form1
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.ClientSize = New System.Drawing.Size(744, 325)
        Me.Controls.AddRange(New System.Windows.Forms.Control() _
          {Me.StatusBar1, Me.Button2, Me.Button1, Me.DataGrid1})
        Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog
        Me.MaximizeBox = False
        Me.Name = "Form1"
        Me.Text = "Query"
        CType(Me.DataGrid1, System.ComponentModel.ISupportInitialize).EndInit()
        Me.ResumeLayout(False)

    End Sub

#End Region

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As _
      System.EventArgs) Handles Button1.Click
        Dim ds As New DataSet()

        ' Connection string
        Dim connString As String = "DATABASE=northwind;SERVER=localhost;Integrated Security=SSPI;"

        ' Commands
        Dim cmdEmpl As String = "SELECT employeeid, lastname FROM Employees"
        Dim cmdCust As String = "SELECT customerid, companyname FROM Customers"

        ' Core command
        ' SELECT o.customerid, o.orderid, o.orderdate, 
        '       o.shippeddate, SUM(od.quantity*od.unitprice) AS price, o.employeeid
        ' FROM orders AS o
        ' INNER JOIN [Order Details] AS od ON o.orderid=od.orderid
        '    WHERE Year(o.orderdate) = @TheYear AND od.orderid=o.orderid 
        '    GROUP BY o.customerid, o.orderid, o.orderdate, o.shippeddate, 
        '             o.employeeid
        '    HAVING SUM(od.quantity) >30
        ' ORDER BY o.customerid
        Dim cmdCore As String = ""
        Dim sb As StringBuilder = New StringBuilder("")
        sb.Append("SELECT o.employeeid, o.customerid, o.orderid, o.orderdate,")
        sb.Append("o.shippeddate, SUM(od.quantity*od.unitprice) AS price ")
        sb.Append("FROM orders AS o ")
        sb.Append("INNER JOIN [Order Details] AS od ON _
          o.orderid=od.orderid ")
        sb.Append("WHERE Year(o.orderdate)=@TheYear AND _
          od.orderid=o.orderid ")
        sb.Append("GROUP BY o.customerid, o.orderid, o.orderdate, _
          o.shippeddate, o.employeeid ")
        sb.Append("HAVING SUM(od.quantity) >@TheQuantity ")
        sb.Append("ORDER BY o.customerid")
        cmdCore = sb.ToString()

        ' Execute commands
        Dim conn As SqlConnection = New SqlConnection(connString)
        Dim adapter As SqlDataAdapter = New SqlDataAdapter()

        conn.Open()
        adapter.SelectCommand = New SqlCommand(cmdCore, conn)
        adapter.SelectCommand.Parameters.Add("@TheYear", 1997)
        adapter.SelectCommand.Parameters.Add("@TheQuantity", 30)
        adapter.Fill(ds, "Orders")
        adapter.SelectCommand = New SqlCommand(cmdCust, conn)
        adapter.Fill(ds, "Customers")
        adapter.SelectCommand = New SqlCommand(cmdEmpl, conn)
        adapter.Fill(ds, "Employees")
        conn.Close()

        ' Create Orders2Employees relation (column #0 on Orders)
        Dim relOrder2Employees As DataRelation
        relOrder2Employees = New DataRelation("Orders2Employees", _
            ds.Tables("Employees").Columns("employeeid"), _
            ds.Tables("Orders").Columns("employeeid"))
        ds.Relations.Add(relOrder2Employees)

        ' Create Orders2Customers relation (column #1 on Orders)
        Dim relOrders2Customers As DataRelation
        relOrders2Customers = New DataRelation("Orders2Customers", _
            ds.Tables("Customers").Columns("customerid"), _
            ds.Tables("Orders").Columns("customerid"))
        ds.Relations.Add(relOrders2Customers)

        ' Add related columns for display
        ds.Tables("Orders").Columns.Add("Employee", GetType(String), _
          "Parent(Orders2Employees).lastname")
        ds.Tables("Orders").Columns.Add("Customer", GetType(String), _
         "Parent(Orders2Customers).companyname")

        ' Show data
        DataGrid1.AllowNavigation = False
        DataGrid1.DataSource = ds
        DataGrid1.DataMember = "Orders"
    End Sub



    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As _
      System.EventArgs) Handles Button2.Click
        Dim ds As New DataSet()

        ' Connection string
        Dim connString As String = "DATABASE=northwind;SERVER=localhost;Integrated Security=SSPI;"

        ' Core command
        'SELECT o.customerid, od.orderid, o.orderdate, o.shippeddate, 
        ' SUM(od.quantity*od.unitprice) AS price,
        ' c.companyname, e.lastname FROM Orders AS o 
        'INNER JOIN Customers AS c ON c.customerid=o.customerid
        'INNER JOIN Employees AS e ON e.employeeid=o.employeeid
        'INNER JOIN [Order Details] AS od ON o.orderid=od.orderid
        '    WHERE Year(o.orderdate) = @TheYear AND od.orderid=o.orderid 
        '    GROUP BY o.customerid, c.companyname, od.orderid, 
        '       o.orderdate, o.shippeddate, e.lastname
        '    HAVING SUM(od.quantity) >@TheAmount
        'ORDER BY o.customerid

        Dim cmdCore As String = ""
        Dim sb As StringBuilder = New StringBuilder("")
        sb.Append("SELECT o.customerid, c.companyname, e.employeeid, e.lastname, ")
        sb.Append("od.orderid, o.orderdate, o.shippeddate, ")
        sb.Append(" SUM(od.quantity*od.unitprice) AS price ")
        sb.Append(" FROM Orders AS o ")
        sb.Append("INNER JOIN Customers AS c ON c.customerid=o.customerid ")
        sb.Append("INNER JOIN Employees AS e ON e.employeeid=o.employeeid ")
        sb.Append("INNER JOIN [Order Details] AS od ON o.orderid=od.orderid  ")
        sb.Append("    WHERE Year(o.orderdate) = @TheYear AND od.orderid=o.orderid  ")
        sb.Append("    GROUP BY o.customerid, c.companyname, od.orderid,  ")
        sb.Append("       o.orderdate, o.shippeddate, e.employeeid, e.lastname ")
        sb.Append("    HAVING SUM(od.quantity) >@TheAmount ")
        sb.Append("ORDER BY o.customerid ")
        cmdCore = sb.ToString()

        ' Execute commands
        Dim conn As SqlConnection = New SqlConnection(connString)
        Dim adapter As SqlDataAdapter = New SqlDataAdapter()

        conn.Open()
        adapter.SelectCommand = New SqlCommand(cmdCore, conn)
        adapter.SelectCommand.Parameters.Add("@TheYear", 1997)
        adapter.SelectCommand.Parameters.Add("@TheAmount", 30)
        adapter.Fill(ds, "Orders")
        conn.Close()

        ' Split data
        Dim table As DataSet = SplitData(ds)

        ' Show data
        DataGrid1.AllowNavigation = True
        DataGrid1.DataSource = table

        ' Status bar
        Dim t As String = String.Format("{0} orders. {1} customers. {2} employees.", _
            table.Tables("Orders").Rows.Count, table.Tables("Customers").Rows.Count, _
              table.Tables("Employees").Rows.Count)
        StatusBar1.Text = t
    End Sub


    Function SplitData(ByVal ds As DataSet) As DataSet
        Dim _dataset As New DataSet()

        ' Make a full worker copy of the DataSet
        _dataset = ds.Copy()

        CreateCustomers(_dataset, ds)
        CreateEmployees(_dataset, ds)

        ' Remove columns from Orders(companyname [2] and lastname [4])
        ' ***************************************************
        _dataset.Tables("Orders").Columns.RemoveAt(1)
        _dataset.Tables("Orders").Columns.RemoveAt(3)
        ' ***************************************************

        Return _dataset
    End Function

    ' Create Customers
    Sub CreateCustomers(ByVal _dataset As DataSet, ByVal orig As DataSet)
        Dim _customers As DataTable = orig.Tables("Orders").Clone()
        _customers.TableName = "Customers"

        ' Remove unneeded columns (no data involved): keep 1-2
        Dim i As Integer
        For i = 2 To _customers.Columns.Count - 1
            _customers.Columns.RemoveAt(2)
        Next

        ' Fill with data
        Dim row As DataRow
        Dim customerKey As String = ""
        For Each row In _dataset.Tables("Orders").Rows
            ' Already sorted by CustomerID
            If customerKey <> row("customerid") Then
                ' select distinct
                _customers.ImportRow(row)
                customerKey = row("customerid")
            End If
        Next

        ' Add to the DataSet
        _dataset.Tables.Add(_customers)
    End Sub


    ' Create Employees
    Sub CreateEmployees(ByVal _dataset As DataSet, ByVal orig As DataSet)
        Dim _employees As DataTable = orig.Tables("Orders").Clone()
        _employees.TableName = "Employees"

        ' Remove unneeded columns (no data involved): keep 3-4
        _employees.Columns.RemoveAt(0)
        _employees.Columns.RemoveAt(0)
        Dim i As Integer
        For i = 2 To _employees.Columns.Count - 1
            _employees.Columns.RemoveAt(2)
        Next

        ' Fill with data (must sort by employeeid first)
        Dim employeeKey As Integer = 0
        Dim view As DataView = New DataView(_dataset.Tables("Orders"))
        view.Sort = "employeeid"

        Dim rowView As DataRowView
        For Each rowView In view

            If employeeKey <> Convert.ToInt32(rowView("employeeid")) Then
                ' select distinct
                _employees.ImportRow(rowView.Row)
                employeeKey = Convert.ToInt32(rowView("employeeid"))
            End If
        Next

        ' Add to the DataSet
        _dataset.Tables.Add(_employees)
    End Sub

End Class