Search code examples
linqgridviewwebformsparent-childasp.net-dynamic-data

GridView DynamicField child property generates "table does not have column" error


I'm having a problem with DynamicFields in a GridView. I'm trying to get a field with a property from a related entity, something like "Customer.Name" in an Order entity but always get the error "The table 'Order' does not have a column named 'Customer.Name'."

I'm including the Customer entity in linq query.

If I change DynamicField by BoundField all works fine.

Edit: This is the code...

<asp:GridView ID="grvActivities" runat="server"
                Caption="<%$ Resources:QuasarApp, MyOpenActivities %>" AutoGenerateColumns="false"
                DataKeyNames="ActivityId" ItemType="Quasar.Model.Activity"
                ShowHeaderWhenEmpty="True" AllowSorting="True"
                ShowFooter="True" CssClass="table table-striped table-bordered table-hover table-condensed table-responsive"
                SelectMethod="grvActivities_GetData"
                UpdateMethod="grvActivities_UpdateItem"
                OnRowCommand="grvActivities_RowCommand">
                <Columns>
                    <asp:HyperLinkField ControlStyle-CssClass="nounderline fa fa-edit"
                        DataNavigateUrlFields="ActivityId" DataNavigateUrlFormatString="~/Activities/Edit.aspx?RecordId={0}"
                        ItemStyle-Width="25px" ItemStyle-HorizontalAlign="Center" ItemStyle-VerticalAlign="Middle" />
                    <asp:TemplateField ShowHeader="false">
                        <ItemTemplate>
                            <asp:LinkButton ID="Complete" runat="server" CommandName="Complete" CommandArgument='<%# Eval("ActivityId") %>'
                                CssClass="nounderline fa fa-check-square-o" ToolTip="<%$ Resources:QuasarApp, MarkAsCompleted %>" />
                        </ItemTemplate>
                    </asp:TemplateField>
                    <asp:DynamicField DataField="StartDate" DataFormatString="{0:g}" />
                    <asp:DynamicField DataField="DueDate" DataFormatString="{0:g}" />
                    <asp:DynamicField DataField="EndDate" DataFormatString="{0:g}" />
                    <asp:DynamicField DataField="Name" />
                    <asp:DynamicField DataField="Activity.Customer.Name" />
                    <asp:DynamicField DataField="Lead" />
                    <asp:DynamicField DataField="PriorityLevel" />
                    <asp:DynamicField DataField="ActivityType" />
                    <asp:DynamicField DataField="Status" />
                    <asp:DynamicField DataField="CreatedBy" />
                    <asp:ButtonField ButtonType="Link" CommandName="Delete" ControlStyle-CssClass="nounderline fa fa-eraser"
                        ItemStyle-Width="25px" ItemStyle-HorizontalAlign="Center" ItemStyle-VerticalAlign="Middle" />
                </Columns>
            </asp:GridView>

Codebehind:

public IQueryable<Activity> grvActivities_GetData()
    {
        var query = _uow.Activities.GetMany(a =>
            a.IsActive
            && a.AccountManagerId == currentAccountManager
            && a.EndDate == null,
            q => q.OrderByDescending(s => s.StartDate),
            includeProperties: "Customer, Lead, ActivityType");
        return query;
    }

Edit2: Hi, I've found that with this column:

<asp:TemplateField HeaderText="<%$ Resources:QuasarApp, Customer %>">
                        <ItemTemplate>
                            <asp:Label Text="<%# Item.Customer != null ? Item.Customer.Name : String.Empty %>" runat="server" />
                        </ItemTemplate>
                    </asp:TemplateField>

it works fine, but I'm loosing all sorting, etc., capabilities. Why if navigation property is comming in the datasource, DynamicField cannot found this property?


Solution

  • For navigational properties you should use only this:

    <asp:DynamicField DataField="Customer" />
    

    Dynamic data will show the first string property of your class. Or you can force with annotations:

    [DisplayColumn("Name")]
    public class Customer
    

    But if you are using EF6 it's necessary to install the provider [http://blogs.msdn.com/b/webdev/archive/2014/02/28/announcing-the-release-of-dynamic-data-provider-and-entitydatasource-control-for-entity-framework-6.aspx][1]

    and register your model in global.asax.cs:

    void Application_Start(object sender, EventArgs e)
        {            
            MetaModel DefaultModel = new MetaModel();
            DefaultModel.RegisterContext(new  Microsoft.AspNet.DynamicData.ModelProviders.EFDataModelProvider(
                                         () => new YOURCONTEXT()),
                                         new ContextConfiguration { ScaffoldAllTables = false });
        }
    

    and finally set the page_init code:

    protected void Page_Init()
    {
    
        grvActivities.SetMetaTable(MetaTable.GetTable(typeof(Activity)));
    }