如何获取用于生成asp:GridView组合字段的DataSource行源值?
ASP.NET GridView编辑时获取原始数据行的方案
核心结论
不能直接通过e.NewEditIndex访问绑定的原始DataRow——因为GridView默认不会将完整的DataSource持久化到ViewState中,绑定完成后DataItem会被释放。你需要通过以下两种常见方式获取对应行的原始数据:
方案1:重新从数据库查询(推荐)
这是最可靠的方式,避免依赖状态存储带来的一致性问题,只需新增一个根据ID查询单条订单行的逻辑:
protected void gvOrderLines_RowEditing(object sender, System.Web.UI.WebControls.GridViewEditEventArgs e) { UpdateID = (int)gvOrderLines.DataKeys[e.NewEditIndex].Value; // 根据ID查询单条订单行数据 DataTable dt = DbUtil.GetAppTable( "usp_order_lines_by_id @id=@id", new Hashtable { { "id", UpdateID } }, commandTimeoutSeconds: 180); if (dt.Rows.Count > 0) { DataRow row = dt.Rows[0]; tbCode.Text = row.Field<string>("product_code"); tbName.Text = row.Field<string>("product_name"); tbQuantity.Text = row.Field<double>("quantity").ToString("f2"); tbPrice.Text = row.Field<double>("price").ToString("f3"); } gvOrderLines.EditIndex = -1; gvOrderLines.DataBind(); }
注:需要对应创建支持ID参数的存储过程usp_order_lines_by_id,或者修改现有存储过程以支持ID过滤。
方案2:将DataTable存入Session/ViewState(性能优先)
如果不想重复查询数据库,可以在绑定GridView时将完整DataTable存入Session,后续从Session中检索:
绑定阶段存储DataTable
private void LoadGridViewOrderLines() { DataTable dt = DbUtil.GetAppTable( "usp_order_lines @order_code=@order_code", new Hashtable { { "order_code", OrderCode } }, commandTimeoutSeconds: 180); // 省略添加html_text_info列及格式化的代码... gvOrderLines.DataSource = dt; gvOrderLines.DataBind(); // 将DataTable存入Session Session["OrderLinesDataTable"] = dt; }
编辑阶段检索数据
protected void gvOrderLines_RowEditing(object sender, System.Web.UI.WebControls.GridViewEditEventArgs e) { UpdateID = (int)gvOrderLines.DataKeys[e.NewEditIndex].Value; DataTable dt = Session["OrderLinesDataTable"] as DataTable; if (dt != null) { // 根据ID筛选对应行 DataRow[] targetRows = dt.Select($"ID = {UpdateID}"); if (targetRows.Length > 0) { DataRow row = targetRows[0]; tbCode.Text = row.Field<string>("product_code"); tbName.Text = row.Field<string>("product_name"); tbQuantity.Text = row.Field<double>("quantity").ToString("f2"); tbPrice.Text = row.Field<double>("price").ToString("f3"); } } gvOrderLines.EditIndex = -1; gvOrderLines.DataBind(); }
注:Session会占用服务器内存,ViewState会增加页面体积,需根据业务场景权衡使用。
内容的提问来源于stack exchange,提问作者pepr
相关产品推荐
相关产品推荐

