【问题标题】:How do I create a DataTable variable that is accessible by every method on the page?如何创建页面上的每个方法都可以访问的 DataTable 变量?
【发布时间】:2021-03-09 03:16:28
【问题描述】:

我是 ASP.NET C# 的新手。 我想创建一个持久的 DataTable 并且可以通过页面上的每个方法访问。列表视图控件绑定到数据表,因此当用户向数据表添加一行时,它会显示在列表视图中。 我希望 DataTable 一直存在,直到用户离开页面(或 F5 刷新)。 重要的是每个用户都必须有自己的 DataTable 实例,因此 ListView 只显示该用户的行,而不显示其他用户的行。 我尝试如下声明一个静态变量:

namespace MySite
{
    public partial class MyPage: System.Web.UI.Page
    {
        public static DataTable dtbMyDataTable = new DataTable();

但我随后发现,像这样的静态变量会在应用程序域的生命周期内持续存在。此外,不同的用户不会获得自己的数据表实例,因此每个用户都在访问同一个数据表,并且可以在 ListView 中看到每个人的数据。

我也尝试如下声明一个字段:

    public static DataTable dtbMyDataTable { set; get; }

但这产生了同样的问题,用户没有自己的DataTable实例,所以每个用户都可以在ListView中看到其他用户的数据,这不好。

我的另一个想法是在 Page_Load 中创建 DataTable,然后将其存储为会话变量,以便在需要时可以通过其他方法访问 DataTable 中的数据。这也解决了用户只访问自己数据的问题。这样做的问题是,如果用户离开计算机一段时间,会话将超时,并且用户将丢失数据。

非常感谢所有建议。我花了很多时间在谷歌上搜索这个结果却空手而归。

我是 Stack Overflow 的新手,如果我没有正确格式化这个问题,请原谅我。 感谢您的帮助。

【问题讨论】:

  • 类中的其他方法可以访问任何字段。您能否为您的问题添加更多细节?
  • 这是一个网络应用程序。管理状态是一门艺术。将其置于会话中可能是可行的方法,但不要依赖它始终存在(例如,您打算如何知道用户已从页面导航,或者只是关闭了浏览器选项卡)。您需要设计您计划如何管理用户、他们的身份验证/授权、他们的会话和他们的状态。如果您跨多个服务器进行负载平衡,它会变得更加有趣
  • 似乎你试图让服务器记住太多;服务器本身不应该为每个并发用户单独保存大量用户数据,持续数小时。您应该更多地考虑跟踪用户 ID,将用户数据保存在其他地方(数据库),加载并在他们需要时将其提供给他们,接受来自他们的更新(或自动保存例程定期推送微小位)他们想保存它,并将其修补到您的数据存储中..
  • 可能还值得指出的是,您似乎正在开发一个 Web 表单应用程序,这至少比微软当前的 Web 技术重点落后了几代(紧随其后的是 MVC,现在是 Blazor) - 你真的想将它用于新开发者吗?
  • 从概念上讲,这就是所有网络表单对您的页面数据所做的 - 您建议将 csv 放在隐藏字段中,它会将数据表放在视图状态中 - 所有这些都来回穿梭并在每一端恢复(但是您的 csv 想法是手动完成的)因此仍然存在“数据必须存储在某处”的概念-它要么在服务器的会话中,要么在跨管间传输的数据中,要么在客户端中..或者您采取一些技巧以尽可能减少,将大部分留在数据库中并使用 Json/xhr 发送比特,这是现代方式.. 有点像 80 年代的大型机 :)

标签: c# asp.net datatable scope


【解决方案1】:

您只需要在更大的范围内维护变量的声明,但在 Page_Load 中加载值,并检查它是否是回发:

namespace MySite
{
    public partial class MyPage: System.Web.UI.Page
    {
        public static DataTable dtbMyDataTable = new DataTable();

        protected void Page_Load(object sender, EventArgs e)
        {
           if (!IsPostBack)
           {
            dtbMyDataTable = LoadData(userID);
           }
           else
           {
              //process submitted values by the user here
           }
      }
}

【讨论】:

  • 谢谢加布里埃尔。我有一种方法,用户手动将行添加到 DataTable,但不幸的是,在更大范围内声明 DataTable 意味着 ListView 将显示所有用户输入的数据,而不是那个特定用户..
  • 用Session大概也可以做同样的循环,值得一试
【解决方案2】:

好吧,正如您所注意到的,列表视图、网格视图等可以用数据表填充。你可以循环/交互gridview。但是,你的桌子呢?

你必须自己坚持。有几种方法可以做到这一点。

如果表很小(比如只有 50-100 行),那么保存该表是合理的。您可以将表放在 session() 中(服务器端存储 - 每个用户)。

或者您可以使用 ViewState。这是每个浏览器页面。

所以,你经常看到这样说:

public class HotelEdit : System.Web.UI.Page
{
private DataTable MyTable;

protected void Page_Load(object sender, System.EventArgs e)
{
    if (System.Web.UI.Page.IsPostBack == false)
        LoadGrid();
    else
        MyTable = System.Web.UI.Page.Session["MyTable"];
}

public void LoadGrid()
{
    using (SqlCommand cmdSQL = new SqlCommand("SELECT * from tblHotels ORDER by HotelName", new SqlConnection(My.Settings.Test3)))
    {
        cmdSQL.Connection.Open();
        MyTable.Load(cmdSQL.ExecuteReader);
        ListView1.DataSource = MyTable;
        ListView1.DataBind();
    }

    System.Web.UI.Page.Session["MyTable"] = MyTable;
}

protected void cmdEdit_Click(object sender, EventArgs e)
{
    Button btn = sender;
    int RowID = btn.Attributes.Item("RowID");

    RowEdit(RowID);
}

public void RowEdit(int RowID)
{
    HotelList.Style("display") = "none";
    MyRedit.Style("display") = "normal";

    fLoader(MyRedit, MyTable.Rows(RowID));
}
}

因此,当我单击网格行时,按钮会运行 RowEdit - 请注意我如何将用户选择的行传递给名为 fLoader 的例程(它是一个编辑器例程) - 我使用范围为的“MyTable”整个表格。

如前所述,在大多数情况下,您通常会重新加载表,但对于“小”表,您可以按照上述方式持久化数据表,并在所有事件和代码中使用它那个页面。

【讨论】:

    猜你喜欢
    • 2019-02-02
    • 2015-09-20
    • 2020-06-05
    • 2015-02-14
    • 1970-01-01
    • 2020-10-21
    • 1970-01-01
    相关资源
    最近更新 更多