.NET, Programming, Visual Web Developer

ASP.NET: Using Hierarchical Data with ObjectDataSource

05.03.08 | 1 Comment

When Microsoft introduced the SqlDataSource, they made it very easy to add database connectivity to your ASP.NET pages with a minimum of programming. The SqlDataSource (and the related AccessDataSource) allow you to define database connections declaratively – that is, you define what data they will retrieve and how to manipulate it inside the web page, instead of writing code to provide these functions. Here’s a sample of what an SqlDataSource might look like:

<asp:SqlDataSource ID="SampleDataSource" runat="server"
ConnectionString="Data Source=localhost;Initial Catalog=SampleDB;Integrated Security=True"
SelectCommand="GetSampleData" SelectCommandType="StoredProcedure">

Since SQL Server can return multiple data sets in a single request, the SqlDataSource also made it easy to work with hierarchical data. In other words, if you have an Author record, it’s pretty simple to get a list of Book records associated with it. Microsoft has an in-depth article on this worth reading. For now we’ll just look at a simple example.

Let’s start by assuming that we have a data source called AuthorDatasource with tables named Author and Book, and a relation between them named Author-BookRelation. We then create a FormView called AuthorFormView:

<asp:FormView ID="AuthorFormView" runat="server"

Next we’ll create a DataList to display the books associated with this author:

<asp:DataList ID="BookList" runat="server"
DataSource='<%# Container.DataItem.CreateChildView(Author-BookRelation) %>'

Instead of assigning a DataSourceID, we’re providing the actual data using CreateChildView to create a DataView. When you provide the data this way, however, you do lose the ability to use the declared insert, update, and delete statements for the child data – you have to implement this yourself, in code. You can still use the declared commands on the parent, though.

(Note: In this example it isn’t particularly useful to use CreateChildView – it would be trivial to create another data source and select only the books assigned to this author. It’s much nicer to be able to do this when you have multiple parent records, or parent-child-grandchild data.)

But direct data access is the old school way of doing things. Microsoft has introduced a new datasource, the ObjectDataSource, which facilitates separating the display of data (web page), from the business logic and database layers. And ObjectDataSource does not work with hierarchical data. Or… does it?

Actually there is a way to get it to work, and it’s not that complicated.

Going back to our Author – Book example, let’s create a couple of objects. (I’m not even going to pretend to use a data-access layer here – we’ll pretend the data appears by magic.) First we’ll look at the Library object, which will supply the lists of authors and books:

Public Class Library
  Public Shared Function GetAuthors() As List(Of Author)
    Return AuthorList
  End Function
End Class

If you wanted to select a single author, you could create a function GetAuthorByID which would accept a parameter of the appropriate type. Next let’s look at the Author object:

Public Class Author
  Public AuthorID As Integer
  Public AuthorName As String
  Public AuthorDescription As String
End Class

Now we’ve defined the objects we want to use, let’s create the ObjectDataSource:

<asp:ObjectDataSource ID="AuthorDatasource" runat="server"
SelectMethod="GetAuthors" TypeName="Biblio" DataObjectTypeName="Author">

What does this tell us? It tells us that ASP.NET will use the Biblio class’s GetAuthors method to return a list of type Author. We can then bind our controls to the fields such as AuthorName, etc.

So – how would we get and bind a list of books, eh, smart guy? We add one more property to our Author object:

Public Class Author
  Public AuthorBooks As List(Of Book)
End Class

A DataSource property can work with any class that implements either IEnumerable or IList (or so I’ve been told). So, updating the code we used above, we now have this:

<asp:DataList ID="BookList" runat="server"
DataSource='<%# CType(Container.DataItem, Author).Books %>'

I don’t know if the CType is absolutely required but it doesn’t hurt. The result – we can now painlessly display the list of books from the Author object.

You can load up the data either by passing a Dataset object from your data access layer and then grinding through all the data, or (my favorite) you can define the XML output of your dataset with an XSD schema, use the GetXML method, and serialize this XML into the objects directly.

Of course I’m leaving out the code to update the books, insert new records, etc., but that should be simple for any semi-intelligent programmer (right?).

Now I don’t know everything about ASP.NET, this data isn’t a particularly good example, and I’m sure there’s plenty of naivete in what I’ve written here, but I still think this can be a useful technique to display related data using the ObjectDatasource.

If this code helps you out, be sure to let me know in the comments.

1 Comment

have your say

Add your comment below, or trackback from your own site. Subscribe to these comments.

Be nice. Keep it clean. Stay on topic. No spam.

You can use these tags:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>