从数据表中删除的行也从创建数据表的会话变量中删除
本文关键字:删除 数据表 会话 变量 创建 | 更新日期: 2023-09-27 18:11:17
在处理存储在会话变量中的数据表时,我注意到了一些奇怪的行为。从从会话变量创建的数据表中删除一行似乎也会修改会话变量,如下所示。
<asp:GridView ID="gvResults" runat="server" DataKeyNames="id">
<Columns>
<asp:TemplateField ShowHeader="False">
<ItemTemplate>
<asp:Button ID="btnSelectUserToRemove" runat="server" CausesValidation="false" CommandName="Remove" Text="Select" CommandArgument='<%# Eval("id") %>' OnCommand="Command" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
public partial class Test : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
DataTable dtResults = new DataTable();
dtResults.Columns.Add("id");
dtResults.Rows.Add();
dtResults.Rows[0]["id"] = "1";
dtResults.Rows.Add();
dtResults.Rows[1]["id"] = "2";
Session["id"] = dtResults;
gvResults.DataSource = dtResults;
gvResults.DataBind();
}
}
protected void Command(object sender, CommandEventArgs e)
{
if (e.CommandName == "Remove")
{
DataTable dtTemp = (DataTable)Session["id"];
for (Int32 i = 0; i < dtTemp.Rows.Count; i++)
{
if (e.CommandArgument.ToString() == dtTemp.Rows[i]["id"].ToString())
{
dtTemp.Rows[i].Delete(); //Should just remove the row from the datatable.
}
}
dtTemp.AcceptChanges();
}
DisplayData();
}
protected void DisplayData()
{
gvResults.DataSource = (DataTable)Session["id"];
gvResults.DataBind(); //Should display both rows because I did not save the modified datatable back to this session variable.
}
}
我不会将修改后的dtTemp
数据表保存回Session["id"]
变量。根据我的理解,dtTemp
中应该有1行,因为调用DisplayData
时删除了一行,Session["id"]
中应该有2行。但是,DisplayData
运行后,网格视图中只显示一行。
我希望有人能阐明为什么会发生这种情况。
这是因为dtTemp
和会话变量都是指向同一对象的对象引用。
此行:
DataTable dtTemp = (DataTable)Session["id"];
不做你认为它会做的事。由于DataTable
是一个引用类型,您只是获取一个指向该对象在内存中位置的指针(恰好位于SessionState变量中(,而不是创建它的新副本
如果您想在不修改Session中的DataTable
的情况下对其进行操作,则需要研究克隆模式,例如"如何在.NET中对对象进行深度复制(特别是C#(?"?