【问题标题】:Rows removed from a datatable are also removed from the session variable that created the datatable从数据表中删除的行也会从创建数据表的会话变量中删除
【发布时间】:2014-08-25 00:13:25
【问题描述】:

在处理存储在会话变量中的数据表时,我注意到一些奇怪的行为。从会话变量创建的数据表中删除一行似乎也会修改会话变量,如下所示。

<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 时删除了 1 行,Session["id"] 中应该有 2 行。但是,DisplayData 运行后,gridview 中只显示一行。

我希望有人可以解释为什么会发生这种情况。

【问题讨论】:

    标签: c# asp.net session datatable


    【解决方案1】:

    这是因为dtTemp 和会话变量都是指向同一个对象的对象引用。

    【讨论】:

    • 谢谢。您的回答以及 mkocubinski 的帮助。我创建了一个新数据表,从 dtTemp 克隆了列,然后使用 ImportRow 函数仅复制我需要的数据。
    【解决方案2】:

    这一行:

    DataTable dtTemp = (DataTable)Session["id"];
    

    不做你认为它做的事。由于DataTable 是一种引用类型,因此您只是在获取指向该对象在内存中的位置(恰好位于 SessionState 变量中)的指针,而不是创建它的新副本。

    如果您想在不修改 Session 的情况下对 DataTable 进行操作,则需要查看克隆模式,例如 How do you do a deep copy of an object in .NET (C# specifically)?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-06-03
      • 2021-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-10
      相关资源
      最近更新 更多