Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net 使用实体框架3.5在asp gridview中更新后绑定外键_Asp.net_Entity Framework - Fatal编程技术网

Asp.net 使用实体框架3.5在asp gridview中更新后绑定外键

Asp.net 使用实体框架3.5在asp gridview中更新后绑定外键,asp.net,entity-framework,Asp.net,Entity Framework,我试图解决这些问题已经有一段时间了。在asp gridview中使用外键创建数据绑定时,编辑一行并在dropbox中更改外键。例如,保存更改并返回视图模式(编辑行=-1),外键列中的值将消失(除非未更改)。但是,如果刷新页面(不再次发送数据),则会正确显示值,并按预期进行更改 这也发生在从asp网格视图继承的SPGridView(sharepoint网格视图)中 让我向您展示一个仅使用更新方法的非常简化的示例: (希望不要太简单) 网格 <asp:GridView ID="exa

我试图解决这些问题已经有一段时间了。在asp gridview中使用外键创建数据绑定时,编辑一行并在dropbox中更改外键。例如,保存更改并返回视图模式(编辑行=-1),外键列中的值将消失(除非未更改)。但是,如果刷新页面(不再次发送数据),则会正确显示值,并按预期进行更改

这也发生在从asp网格视图继承的SPGridView(sharepoint网格视图)中

让我向您展示一个仅使用更新方法的非常简化的示例: (希望不要太简单)

网格

<asp:GridView 
    ID="exampleGridView" 
    runat="server" 
    DataKeyNames="Id" 
    AutoGenerateColumns="false"
    OnRowUpdating="UpdateClick"
    OnRowDataBound="RowDataBound">
    <Columns>
        <asp:TemplateField HeaderText="Id">
            <ItemTemplate>
                <asp:Label ID="Id" runat="server" Text='<%# Bind("Id") %>' />
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Login">
            <ItemTemplate>
                <asp:Label ID="Login" runat="server" Text='<%# Bind("Login") %>' />
            </ItemTemplate>
            <EditItemTemplate>
                <asp:TextBox ID="EditLoginTextBox" runat="server" Text='<%# Bind("Login") %>' Enabled="false" />
            </EditItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Role">
            <ItemTemplate>
                <asp:Label ID="Role" runat="server" Text='<%# Bind("Role.Title") %>' />
            </ItemTemplate>
            <EditItemTemplate>
                <asp:DropDownList ID="EditRoleDropDownList" runat="server" />
            </EditItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Action">
        <ItemTemplate>
            <asp:LinkButton ID="EditLinkBtn" runat="server" CommandName="Edit" Text="edit" />
        </ItemTemplate>
        <EditItemTemplate>
            <asp:LinkButton ID="UpdateLinkBtn" runat="server" CommandName="Update" Text="update" />
        </EditItemTemplate>
    </asp:TemplateField>
    </Columns>
</asp:GridView>
protected void UpdateClick(object sender, System.Web.UI.WebControls.GridViewUpdateEventArgs e)
{
    // context taken from constructor, created at the beginning of a request and disposed at the end of a request
    User user = this.ctx.Users.First(u => u.Id == id);

    GridViewRow row = this.exampleGridView.Rows[e.RowIndex];

    user.Login = ((TextBox)row.FindControl("EditLoginTextBox")).Text;

    int roleId =int.Parse(((DropDownList)row.FindControl("EditRoleDropDownList")).SelectedValue);
    if (user.Role.Id != roleId)
    {
        user.Role = ctx.Attach(new Role
        {
            Id = roleId
        });
    }

    this.ctx.SaveChanges();
    this.exampleGridView.EditIndex = -1;
    this.BindGrid();
}

protected void RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow &&
        (e.Row.RowState & DataControlRowState.Edit) == DataControlRowState.Edit)
    {
        var user = (User)e.Row.DataItem;

        var editRoleDropDownList = (DropDownList)e.Row.FindControl("EditRoleDropDownList");
        this.BindRoleDropDownList(editRoleDropDownList);
        editRoleDropDownList.SelectedValue = user.Role.Id.ToString();
    }
}

private void BindGrid()
{
    this.exampleGridView.DataSource = this.ctx.Users.Include(u => u.Role);
    this.exampleGridView.DataBind();
}

private void BindRoleDropDownList(DropDownList roleDropDownList)
{
    // list of roles
    if (this.cachedRoles == null)
    {
        this.cachedRoles = this.ctx.Roles.ToList();
    }

    roleDropDownList.DataSource = this.cachedRoles;
    roleDropDownList.DataValueField = "Id";
    roleDropDownList.DataTextField = "Name";
    roleDropDownList.DataBind();
}

答案比我想象的要简单。问题在于更新方法:

int roleId = int.Parse(((DropDownList)row.FindControl("EditRoleDropDownList")).SelectedValue);
if (user.Role.Id != roleId)
{
    // this is the problem
    user.Role = ctx.Attach(new Role
    {
        Id = roleId
    });
}
问题是我用这个新对象覆盖了角色,它的role.Title显然等于空字符串。物体就在那里。因此,正确的解决方案如下:

int roleId = int.Parse(((DropDownList)row.FindControl("EditRoleDropDownList")).SelectedValue);
if (user.Role.Id != roleId)
{
    user.Role = this.ctx.Roles.First(r => r.Id == roleId);
}