Click here to Skip to main content
15,890,897 members
Articles / Programming Languages / Visual Basic
Article

Databinding with Cross Reference table (many to many)

Rate me:
Please Sign up or sign in to vote.
2.93/5 (14 votes)
20 Apr 2004 99.9K   34   11
This article shows how to databind master and details DataGrids (Winforms) when using a cross reference table.

Introduction

I have seen many posts that have gone unanswered about how to databind a master table to a details table when there is a third table that holds the cross references between them.

Here is an example of a database with this structure:

Sample screenshot

Here we go:

First, we need to fill a DataSet.

VB
Public Function FillDataSet() as DataSet
    Dim daNames As OleDbDataAdapter
    Dim daPhoneNumbers As OleDbDataAdapter
    Dim daNamePhone As OleDbDataAdapter
    Dim cmd As OleDbCommand
    Dim reader As OleDbDataReader
    Try
        conn = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; "_
               & "Data Source=" & "D:\_MySource\FundRaiser\FundRaising.mdb")
        conn.Open()
        ds = New DataSet

        daNames = New OleDbDataAdapter
        Dim s As OleDbCommandBuilder = New OleDbCommandBuilder(daNames)
        ds = GetDataSet(ds, conn, daNames, _
             "SELECT * FROM tbl_Names", "tbl_Names")

        daPhoneNumbers = New OleDbDataAdapter
        ds = GetDataSet(ds, conn, daPhoneNumbers, _
             "SELECT * FROM tbl_PhoneNumbers", "tbl_PhoneNumbers")

        daNamePhone = New OleDbDataAdapter
        ds = GetDataSet(ds, conn, daNamePhone, _
             "SELECT * FROM tbl_Name_Phone", "tbl_Name_Phone")

    Catch

    End Try
    conn.Close()
    Return ds
End Function

Public Function GetDataSet(ByVal ds As DataSet, _
  ByVal conn As OleDbConnection, _
  ByVal Adapter As OleDbDataAdapter, _
  ByVal query As String, ByVal TableName As String) As DataSet
    Adapter.SelectCommand = New OleDbCommand(query, conn)
    Adapter.Fill(ds, TableName)
    Return ds
End Function

Next, we need to create the data relationships between the tables.

VB
Public Sub CreateRelations(byref ds as DataSet)
    Dim parentCol As DataColumn
    Dim childCol As DataColumn
    Dim rel As DataRelation

    parentCol = ds.Tables("tbl_Names").Columns("NameID")
    childCol = ds.Tables("tbl_Name_Phone").Columns("NameID")
    ' Create DataRelation.
    rel = New DataRelation("NamePhone", parentCol, childCol)
    ' Add the relation to the DataSet.
    rel.Nested = True
    ds.Relations.Add(rel)

    parentCol = ds.Tables("tbl_Name_Phone").Columns("PhoneNumberID")
    childCol = ds.Tables("tbl_PhoneNumbers").Columns("PhoneNumberID")
    ' Create DataRelation.
    rel = New DataRelation("NamePhone_PhoneNumbers", parentCol, childCol)
    ' Add the relation to the DataSet.
    rel.Nested = True
    ds.Relations.Add(rel)

End Sub

Now, we need to bind the tables to the DataGrids! This is the not so obvious part!!

VB
Private Sub BindDataSet(ByRef ds As DataSet)
    Call dgNames.SetDataBinding(ds, "tbl_Names")
    Call dgPhoneNumbers.SetDataBinding(ds, _
         "tbl_Names.NamePhone.NamePhone_PhoneNumbers")
End Sub

That's it... The key is to use the relationships when binding the second table!!!

I hope my article was helpful. A complete sample will be available soon.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Generalhelp [modified] Pin
niki_nilu25-Feb-08 20:29
niki_nilu25-Feb-08 20:29 
QuestionASP.NET webform? Pin
BBWS1O18-May-05 17:22
BBWS1O18-May-05 17:22 
GeneralDoesn't work either... Pin
mikasa5-Nov-04 9:42
mikasa5-Nov-04 9:42 
GeneralRe: Doesn't work either... Pin
mikasa5-Nov-04 10:00
mikasa5-Nov-04 10:00 
GeneralRe: Doesn't work either... [modified] Pin
Pakico19-Apr-07 1:25
Pakico19-Apr-07 1:25 
GeneralOnly one record returned Pin
nells113-Sep-04 14:57
nells113-Sep-04 14:57 
Hi Stewart

Firstly let me say thank you for a great article.. its given me hope that I don't have to create calculated columns in my cross reference table to achieve this.

I have a Many to Many join that I'm trying to solve with this article. It does appear to work, except it only ever brings back one child record. Here is my diagram:

Sites 1-----------m Contacts
  1                   1
  |                   |
  |                   |
  m                   m
Jobs 1------------m JobContacts  <--(Cross Reference Table)


On my Job form I have a grid to show the contact details of all the contacts related to the current Job.

According to your article I have to reverse the relationship between Contacts and JobContacts so that JobContact is the parent. To do this I have to set:

Dataset.EnforceConstraints = False

or else I get an error because not all my Contacts have matching JobContact records. This isn't too big a deal, so my relations are set as follows:

<br />
MyDataset.EnforceConstraints = False<br />
<br />
MyDataset.Relations.Add("Job_JobContact", _<br />
     MyDataset.Tables("Jobs").Columns("JobID"), _<br />
     MyDataset.Tables("JobContacts").Columns("JobID"))<br />
<br />
MyDataset.Relations.Add("JobContact_Contact", _<br />
     MyDataset.Tables("JobContacts").Columns("ContactID"), _<br />
     MyDataset.Tables("Contacts").Columns("ContactID"))<br />


So then I set up my grid with:

<br />
grdContacts.DataSource = MyDataset.Tables("Jobs")<br />
grdContacts.DataMember = "Job_JobContact.JobContact_Contact"<br />


So this, as I said, appears to work, but only brings back the first record (I should have four shown). I have also created a small standalone app that uses your exact code, except using my database, and the same thing happens.

Have you seen this bring back all the records? and if so what am I doing wrong?? Confused | :confused:

Many thanks
Nells Big Grin | :-D
GeneralRe: Only one record returned Pin
mikasa5-Nov-04 11:49
mikasa5-Nov-04 11:49 
AnswerRe: Only one record returned Pin
Josef Meile21-Sep-05 21:51
Josef Meile21-Sep-05 21:51 
Generalvariables not used Pin
karim ben romdhane23-Aug-04 0:36
karim ben romdhane23-Aug-04 0:36 
GeneralSyntax Not based on .NET Framework version 1.1 Pin
Jose Xavier21-Apr-04 0:53
Jose Xavier21-Apr-04 0:53 
GeneralRe: Syntax Not based on .NET Framework version 1.1 Pin
ss2art21-Apr-04 14:24
ss2art21-Apr-04 14:24 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.