ASP.NET and Business Objects (POCO or LINQ)
If you like architecture, you may realize there are some challenges that come into play when you try to bind data to the interface controls in ASP.NET. Because data is often normalized, and this data is structured in several parent-child relationships, normalizing these for a tablular control like a grid view can be a big challenge. Often, the approach is to use template fields, such as shown below:
<asp:GridView ..>
<Columns>
<asp:TemplateField HeaderText="Child">
<ItemTemplate>
<asp:Label id="lblChildField" runat="server" Text='<%# $((ChildObject)Eval("Child")).ChildProperty %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Essentially, if object Parent has a property Child, this property is of type ChildObject. Now, ChildProperty is a property of the ChildObject type, which is stored in the Child property of the class being bound in this example. I hope I was able to explain that in a way that makes sense. 
So, is there an easier way? Could there be a way to flatten a complex hierarchy more easily? Certainly, a collection could be converted to a data table, or another business object can be used to contain all the important information necessary to display the important information in the grid. I found a variant of option 2 that is useful, in case you are interested.
One of the new features of the .NET 3.0-3.5 frameworks is anonymous types. For instance, I can define the following:
var person = new { Name = "Brian", Age=30 };
And this creates a new object with the signature of the name and age properties. For more information on anonymous types, check these out:
http://weblogs.asp.net/scottgu/archive/2007/05/15/new-orcas-language-feature-anonymous-types.aspx?CommentPosted=true
http://www.developer.com/net/csharp/article.php/3589916
So, suppose you had this schema:
Customer.CustomerID
Customer.CustomerName
Customer.Orders
Customer.Orders represents:
Order.OrderID
Order.OrderDate
Order.OrderTotal
To normalize this, you can use the following approach:
ArrayList list = new ArrayList();
foreach (Customer customer in this.Context.Customers)
{
foreach (Order order in customer.Orders)
{
var item = new
{
CustomerID = customer.CustomerID,
CustomerName = customer.CustomerName,
OrderDate = order.OrderDate,
OrderTotal = order.OrderTotal
}
list.Add(item);
}
}
Notice the anonymous declaration, which creates an anonymous type of CustomerID, CustomerName, OrderDate, and OrderTotal. This anonymous type is added to an array list; all that's needed is an enumerable list to be bound to the grid as such:
this.GridView1.DataSource = list;
this.GridView1.DataBind();
Simply have the grid use the anonymous type properties in the list of bound field columns, and you're good to go. Although this is more work, this is one situation; in some situations, you could simply query and join customers and orders, returning an anonymous type from a LINQ query, and using this to bind to the grid.