Custom Binding With EntityDataSource

Here's a common scenario: you are using an EntityDataSource control which you are binding to a data control, perhaps a ListView, DataGrid, DataList, Repeater, or GridView. The problem is, you want to do some custom binding. This happens, for example, when viewing a master-detail relationship.

What you typically do then is implement a custom event handler for event ItemDataBound (for ListView, DataGrid, DataList and Repeater) or RowDataBound (for GridView) and do something with the e.Item.DataItem property value (in the former cases) or e.Row.DataItem (in the later one), which is, of course, a pointer to your entity object... or is it? Depending on the way you've set up EntityDataSource on your page, it may or may not be.

If you used the EntitySetName property to indicate the name of your entity, it won't work, because the e.Item.DataItem (or e.Row.DataItem) will instead contain a wrapper object:

<asp:EntityDataSource ID="myEntitiesDataSource" runat="server" ConnectionString="name=MyEntities" EntitySetName="Entity"

DefaultContainerName="MyEntities" />

protected void OnItemDataBound(Object sender, RepeaterItemEventArgs e)

{

    Entity entity = e.Item.DataItem as Entity//null

    entity = this.GetWrappedEntity<Entity>(e.Item.DataItem);  //see code below

}

In this case, you must use this in order to get the actual entity: 

protected TEntity GetWrappedEntity<TEntity>(Object dataItem) where TEntity : class

{

    TEntity entity = dataItem
as TEntity;
    if (entity != null)

    {

        return (entity);

    }

    else

    {

        ICustomTypeDescriptor td = dataItem as ICustomTypeDescriptor;        if (td != null)

        {

            return (td.GetPropertyOwner(null) as TEntity);

        }

        else

        {

            return (null);

        }

    }

}

If, however, you skip the EntitySetName property and instead set the CommandText property, everything works as usual:

<asp:EntityDataSource ID="myEntitiesDataSource" runat="server"

ConnectionString="name=MyEntities" CommandText="SELECT VALUE entity FROM MyEntities.Entities AS entity"

DefaultContainerName="MyEntities" />

protected void OnItemDataBound(Object sender, RepeaterItemEventArgs e)

{

    Entity entity = e.Item.DataItem as Entity//ok

}

Hope this saves you some trouble! :-)

Bookmark and Share

                             

No Comments