It is quite often that different customers eventually face the need to use a master-detail hierarchical representation of their data. However most customers are not aware that this is extremely easily achievable using Telerik OpenAccess ORM together with our RadGrid. Furthermore it is achieved without writing ANY code in the code behind file of your project.

Now let’s get to the job!

What will be needed is just one RadGrid and two OpenAccessDataSource controls. The two data source controls will be used to query data from the master and detail tables. In our case we used the Company and Employee tables(one company has many employees).

    public partial class Company
   
{
       
//The 'no-args' constructor required by OpenAccess. 
        public Company()
       
{
       
}

       
[Telerik.OpenAccess.FieldAlias("companyId")]
       
public int CompanyId
       
{
           
get { return companyId; }
           
set { this.companyId = value; }
       
}

       
[Telerik.OpenAccess.FieldAlias("address")]
       
public string Address
       
{
           
get { return address; }
           
set { this.address = value; }
       
}

       
[Telerik.OpenAccess.FieldAlias("name")]
       
public string Name
       
{
           
get { return name; }
           
set { this.name = value; }
       
}

       
[Telerik.OpenAccess.FieldAlias("employees")]
       
public IList<Employee> Employees
       
{
           
get { return employees; }
       
}


   
}
public partial class Employee
   
{
       
//The 'no-args' constructor required by OpenAccess. 
        public Employee()
       
{
       
}

       
[Telerik.OpenAccess.FieldAlias("employeeId")]
       
public int EmployeeId
       
{
           
get { return employeeId; }
           
set { this.employeeId = value; }
       
}

       
[Telerik.OpenAccess.FieldAlias("firstName")]
       
public string FirstName
       
{
           
get { return firstName; }
           
set { this.firstName = value; }
       
}

       
[Telerik.OpenAccess.FieldAlias("lastName")]
       
public string LastName
       
{
           
get { return lastName; }
           
set { this.lastName = value; }
       
}

       
[Telerik.OpenAccess.FieldAlias("phone")]
       
public string Phone
       
{
           
get { return phone; }
           
set { this.phone = value; }
       
}

       
[Telerik.OpenAccess.FieldAlias("ssn")]
       
public string Ssn
       
{
           
get { return ssn; }
           
set { this.ssn = value; }
       
}

       
[Telerik.OpenAccess.FieldAlias("company")]
       
public Company Company
       
{
           
get { return company; }
           
set { this.company = value; }
       
}
       
public int EmployeeCompanyId
       
{
           
get { return company.CompanyId; }            
       
}


   
}
Notice the EmployeeCompanyId property. We will discuss it in a minute as it will make much more sense after we look at the definition of the grid. But first let’s see the definition of the two data source controls:
  <telerik:OpenAccessDataSource ID="OpenAccessDataSource1" runat="server" 
            ObjectContextProvider
="Model.ObjectScopeProvider1, Model" 
            TypeName
="Model.Company">
       
</telerik:OpenAccessDataSource>
   
</div>
   
<telerik:OpenAccessDataSource ID="OpenAccessDataSource2" runat="server" 
        ObjectContextProvider
="Model.ObjectScopeProvider1, Model" 
        TypeName
="Model.Employee" Where="Company.CompanyId == @Company.CompanyId">
       
<WhereParameters>
           
<asp:SessionParameter Name="Company.CompanyId" SessionField="CompanyId" />
        </
WhereParameters>
   
</telerik:OpenAccessDataSource>

As you can see the first one queries all objects from the Company table. The second one returns only those employee that match the selected company id. This id is obtained with a session parameter.
Now let’s define our grid. First we will need to bind the MasterTableView of the grid to the first data source as we want all the company objects to be displayed there. Then we need to bind the second data source to the details table of the grid in order to be displayed for each company. Here is how it is done:

<telerik:RadGrid ID="RadGrid1" runat="server" 
            DataSourceID
="OpenAccessDataSource1" AutoGenerateEditColumn="True" 
            GridLines
="None">
<HeaderContextMenu>
<CollapseAnimation Type="OutQuint" Duration="200"></CollapseAnimation>
</HeaderContextMenu>

<MasterTableView AutoGenerateColumns="False" DataKeyNames="CompanyId" 
                DataSourceID
="OpenAccessDataSource1" AllowAutomaticUpdates="true">    
   
<DetailTables>
       
<telerik:GridTableView runat="server" DataSourceID="OpenAccessDataSource2" DataKeyNames="EmployeeId,EmployeeCompanyId" AllowAutomaticUpdates="true">
       
<ParentTableRelation>
       
<telerik:GridRelationFields DetailKeyField="Company.CompanyId" MasterKeyField="CompanyId" />
        </
ParentTableRelation>
       
</telerik:GridTableView>
   
</DetailTables>
<RowIndicatorColumn>
<HeaderStyle Width="20px"></HeaderStyle>
</RowIndicatorColumn>

<ExpandCollapseColumn Visible="True">
<HeaderStyle Width="20px"></HeaderStyle>
</ExpandCollapseColumn>
   
<Columns>
       
<telerik:GridBoundColumn DataField="CompanyId" DataType="System.Int32" 
            HeaderText
="CompanyId" ReadOnly="True" SortExpression="CompanyId" 
            UniqueName
="CompanyId">
       
</telerik:GridBoundColumn>
       
<telerik:GridBoundColumn DataField="Address" HeaderText="Address" 
            SortExpression
="Address" UniqueName="Address">
       
</telerik:GridBoundColumn>
       
<telerik:GridBoundColumn DataField="Name" HeaderText="Name" 
            SortExpression
="Name" UniqueName="Name">
       
</telerik:GridBoundColumn>
   
</Columns>
</MasterTableView>

<FilterMenu>
<CollapseAnimation Type="OutQuint" Duration="200"></CollapseAnimation>
</FilterMenu>
       
</telerik:RadGrid>
The only tricky part here is that where you specify which fields will be the data keys you can’t really use Company.CompanyID. This is where our EmployeeCompanyId kicks in. Using this property we will “help” the grid to successfully find the correct value required during update. Now you can just start using the grid. Note that if you would like to delete data you will have to enable Cascading delete for the Employees collection in the company class and everything will work out of the box.

We have defined some animations for expanding and collapsing as well, and now RadGrid looks quite “slick”.

I hope you enjoyed this example as much as I did writing it.


Related Posts

Comments