Displaying child entities with ASP.net Dynamic Data
Entity Framework automatically creates navigation to related items. Taking the Chinook database as an example, each album can have many tracks, and this is exposed as myAlbum.Tracks.
The default code generation for Tracks is pretty dismal.
We would like to teach Dynamic Data to render Tracks differently. First, we explain to Dynamic Data that Tracks is a custom type, and therefore has special rendering requirements.
[ScaffoldTable(true)]
[MetadataType(typeof(Album.Metadata))]
public partial class Album
{
public class Metadata
{
[DataType("Tracks")]
public EntityCollection<Track> Tracks;
}
}
Then in the DynamicDataFieldTemplates folder, add a UserControl to render our Tracks data type.
The Tracks UserControl looks like this
<h2>Tracks</h2> <asp:Label Width="300" runat="server" Text='' />
This renders the tracks using a repeater control.
The code behind may look like a lot of code, but in reality it isn’t.
Firstly, we override DataControl. This tells DynamicData that it should use the RepeaterControl inside this user control for rendering.
Secondly, override OnDataBinding. We make sure that only if we are binding to “Tracks” data type, we’d assign Tracks to the Repeater’s DataSource.
Finally, override FieldValue. This works around a limitation of the EntityFramework providers for Dynamic Data (it doesn’t return EntityObjects directly, instead returns EntitySourceDataWrappers which ignore properties which are collections).
using System;
using System.Linq;
using System.Web.UI;
using System.Web.DynamicData;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel;
using DynamicChinook.Model;
using System.Data.Objects.DataClasses;
namespace DynamicChinook.DynamicData.FieldTemplates
{
public partial class Tracks : FieldTemplateUserControl
{
public override Control DataControl
{
get
{
return TrackRepeater;
}
}
protected override void OnDataBinding(EventArgs e)
{
base.OnDataBinding(e);
var metadata = MetadataAttributes.OfType().FirstOrDefault();
if (String.IsNullOrEmpty(FieldValueString) || metadata == null)
return;
if (metadata.DataType == DataType.Custom && metadata.CustomDataType == "Tracks")
{
TrackRepeater.DataSource = FieldValue;
}
}
public override object FieldValue
{
get
{
Album album = WrapperToEntity(this.Row) as Album;
if (album != null)
{
return album.Tracks;
}
else
{
return base.FieldValue;
}
}
set
{
base.FieldValue = value;
}
}
/// <summary>
/// Converts EntitySourceDataWrapper into EntityObject
/// </summary>
///
///
private static EntityObject WrapperToEntity(object wrapper)
{
ICustomTypeDescriptor descriptor = wrapper as ICustomTypeDescriptor;
if (descriptor != null)
{
var prop = descriptor.GetProperties().Cast().First();
return descriptor.GetPropertyOwner(prop) as EntityObject;
}
else
{
return null;
}
}
}
}
And the end result looks something like this.
More work remains to be done for the tracks to be editable.
About this entry
You’re currently reading “ Displaying child entities with ASP.net Dynamic Data ,” an entry on Chui's Counterpoint
- Published:
- 6.25.11 / 11pm
- Category:
- General



Comments are closed
Comments are currently closed on this entry.