使用EntityDataSource在GridView上显示导航属性?

时间:2011-04-04 14:41:13

标签: asp.net entity-framework entity-framework-4 entitydatasource

我有一个EntityDataSource我已映射到实体Resident,它包含两个导航属性(Building1,Room1)。我已将GridView设置为使用此EntityDataSource并将EntityDataSource Include属性设置为Building1,Room1,因此它包含这些导航属性并将这些列添加到GridView。当我运行应用程序而不是显示相关的导航属性时,它显示:webHousingAdmin.Building 如何让它显示实际值? 对于GridView,代码看起来像这样:

        <asp:TemplateField>
            <ItemTemplate>
                <asp:Label ID="lbl1" runat="server" Text='<%# Bind("Building1") %>' />
            </ItemTemplate>
        </asp:TemplateField>

我已经通过使用以下代码显示实际值:

            <asp:TemplateField HeaderText="Building">
            <ItemTemplate>
                <asp:Label ID="lblBuilding" Text='<%# Bind("Building1.building_name") %>' runat="server" />
            </ItemTemplate>
        </asp:TemplateField>

但有更简单的方法吗?这只显示文本,不允许我编辑它...如果我可以做一个理想的边界字段。

2 个答案:

答案 0 :(得分:2)

要在标签中获得有意义的内容,您可以将Building类的标量属性绑定到Label ...

<asp:Label ID="lbl1" runat="server" Text='<%# Bind("Building1.Name") %>' />

...或者你可以覆盖班级的ToString() ......

public class Building
{
    public string Name { get; set; }
    public string AnotherText { get; set; }

    public override string ToString()
    {
        return string.Concat(Name, ", ", AnotherText); // or whatever you like
    }
}

如果将属性绑定到作为类的网格,绑定引擎将调用ToString() - 如果不覆盖{{1},则仅返回完整的类名(命名空间点类名) }。这解释了为什么您只在示例中看到ToString

修改

与此问题并不真正相关:但是如果您尝试将导航属性与webHousingAdmin.Building(而不仅仅是Bind)绑定,以便在数据源和网格之间进行双向通信,则可能会遇到问题。可能它不会起作用。请参阅此相关问题和答案:

Columns of two related database tables in one ASP.NET GridView with EntityDataSource

答案 1 :(得分:0)

这是几年前被问到的,但我找到了同样的答案。这对我有用。在ASPX中,这是遵循所述模型的完整GridView:

<asp:EntityDataSource ID="dsResidents" runat="server"
        ConnectionString="name=connString"
        DefaultContainerName="dbContext"
        EntitySetName="Residents"
        Include="Building"
        EnableUpdate="true" />

    <asp:GridView ID="ResidentGrid" runat="server"
        DataSourceID="dsResidents"
        OnRowUpdating="ResidentsGrid_RowUpdating"
        AutoGenerateColumns="False">
        <Columns>
            <asp:CommandField ShowEditButton="True" />
            <asp:TemplateField Visible="false">
                <ItemTemplate>
                    <asp:Label ID="lblID"
                        Text='<%# Eval("residentId") %>'
                        runat="server" />
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Name">
                <ItemTemplate>
                    <asp:Label ID="lblName"
                        Text='<%# Eval("residentName") %>'
                        runat="server" />
                </ItemTemplate>
            <asp:TemplateField HeaderText="CountryCode">
                <ItemTemplate>
                    <asp:Label ID="lblCountryCode"
                        Text='<%# Eval("Building.number") %>'
                        runat="server" />
                </ItemTemplate>
                <EditItemTemplate>
                    <asp:EntityDataSource ID="dsBuildings" runat="server"
                        ConnectionString="name=connString"
                        DefaultContainerName="dbContext"
                        EntitySetName="Buildings" />

                    <asp:DropDownList ID="ddlBuilding"
                        DataSourceID="dsBuildings"
                        DataTextField="number"
                        DataValueField="id"
                        SelectedValue='<%# Eval("id") %>' <!-- I am not sure about this line -->
                        runat="server" />
                </EditItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>

请注意,如果使用向导创建实体模型,则默认情况下,ConnectionString名称与DefaultContainerName相同。在支持类中添加用于更新网格行的事件处理程序(OnRowUpdating):

protected void ResidentsGrid_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
    // This is for retrieving the entity object for the resident selected
    Label idLabel = (Label)ResidentsGrid.Rows[e.RowIndex].Cells[1].FindControl("lblID");
    int residentId = int.Parse(idLabel.Text);

    // And this is for the building selected in the dropdown
    DropDownList ddl = (DropDownList)ResidentsGrid.Rows[e.RowIndex].Cells[4].FindControl("ddlBuilding");
    // I would like to say that the cell index is the column position but as I know it isn't

    using (dbContext ctx = new dbContext())
    {
        Resident resident = ctx.Residents
            .Where(res => res.residentId == residentId).First();

        Building selectedBuilding = ctx.Buildings
            .Where(bld => bld.id == ddl.SelectedItem.Value).First();

        resident.Building = selectedBuilding;

        ctx.SaveChanges();
    }
}