DataTable疑似丢失数据,是否误覆写而非添加列?代码排查求助
问题诊断与修复方案
1. 最可能的核心原因:ASP.NET WebForms的无状态特性导致数据丢失
在WebForms中,每次页面回发(比如点击按钮)都会重新创建页面类的实例。你声明的类级别DataTable dtResult = new DataTable();会在每次回发时被重新初始化。如果你的操作流程是:
- 先点击Wizard的Finish按钮(触发
Wizard1_FinishButtonClick,此时当前页面实例的dtResult被填充数据) - 再点击
FinishBtn按钮(触发FinishBtn_Click,此时页面重新回发,创建新的页面实例,dtResult被重置为空表)
这种情况下,pushdatatosql访问的是新实例的空表,自然输出为空。
2. 次要可能原因:未将DataRow添加到DataTable集合
从你提供的代码片段来看,你创建了DataRow dr = dtResult.NewRow();,但没有把赋值后的行添加到dtResult的Rows集合中。如果缺少dtResult.Rows.Add(dr);这一步,即使给dr的列赋了值,dtResult里也不会有任何数据。
修复方案
方案一:合并事件逻辑(推荐)
如果FinishBtn就是Wizard的Finish按钮,不需要单独按钮,直接在Wizard1_FinishButtonClick中调用pushdatatosql,确保在同一个回发过程中操作同一个dtResult:
DataTable dtResult = new DataTable(); protected void Wizard1_FinishButtonClick(object sender, WizardNavigationEventArgs e) { // 先清空旧数据,避免重复添加列报错 dtResult.Columns.Clear(); dtResult.Rows.Clear(); // 添加列 dtResult.Columns.Add(new DataColumn("mainevent", typeof(string))); dtResult.Columns.Add(new DataColumn("secondevent", typeof(string))); // 填充数据 foreach (GridViewRow gr in grdOther.Rows) { DataRow dr = dtResult.NewRow(); TextBox box1 = (TextBox)gr.Cells[1].FindControl("你的TextBoxID"); TextBox box2 = (TextBox)gr.Cells[2].FindControl("你的第二个TextBoxID"); dr["mainevent"] = box1.Text; dr["secondevent"] = box2.Text; dtResult.Rows.Add(dr); // 关键步骤:将行添加到DataTable } // 直接调用数据提交方法 pushdatatosql(); } protected void pushdatatosql() { // 这里访问dtResult就能拿到数据了 Console.WriteLine(dtResult.Rows.Count); // 测试输出 // 你的SQL插入逻辑 }
方案二:用ViewState/Session跨回发保存数据
如果必须分开触发事件(比如先填充表再点击另一个按钮提交),需要把dtResult保存到ViewState或Session中,避免回发时丢失:
// 改用属性从ViewState读取/保存DataTable private DataTable dtResult { get { return ViewState["dtResult"] as DataTable ?? new DataTable(); } set { ViewState["dtResult"] = value; } } protected void Wizard1_FinishButtonClick(object sender, WizardNavigationEventArgs e) { DataTable dt = new DataTable(); dt.Columns.Add(new DataColumn("mainevent", typeof(string))); dt.Columns.Add(new DataColumn("secondevent", typeof(string))); foreach (GridViewRow gr in grdOther.Rows) { DataRow dr = dt.NewRow(); TextBox box1 = (TextBox)gr.Cells[1].FindControl("你的TextBoxID"); dr["mainevent"] = box1.Text; dt.Rows.Add(dr); } // 保存到ViewState dtResult = dt; // 这里输出会有数据 Console.WriteLine(dtResult.Rows.Count); } protected void FinishBtn_Click(object sender, EventArgs e) { pushdatatosql(); } protected void pushdatatosql() { // 从ViewState读取数据 DataTable dt = dtResult; Console.WriteLine(dt.Rows.Count); // 现在输出正常 // 你的SQL插入逻辑 }
注意:如果DataTable数据量很大,建议用Session替代ViewState,避免页面体积过大。
内容的提问来源于stack exchange,提问作者BoJack Horseman
相关产品推荐
相关产品推荐

