代码之家  ›  专栏  ›  技术社区  ›  Tillito

内存中有数据的gridview:在保存对象之前将其保存在哪里?

  •  0
  • Tillito  · 技术社区  · 16 年前

    我有一个 GRIDVIEW 用一个 数据源控件 . 我想让用户创建几个对象,然后一次性保存它们。

    背景:我想为菜谱创建一个编辑器。配方有基本属性(如名称和来源)和成分(如100克黄油),我希望用户设置配方的所有属性,并让他定义其成分之前(!!)保存到数据库。此外,还必须能够从列表中删除一种成分。先保存配方,然后定义配料不是一个选项。

    我的问题: 在将原料保存到数据库之前,我应该将它们保存在哪里?

    我发现:

    1. viewstate不是选项,因为obectdatasource的getdata方法是静态的,因此无法访问viewstate。
    2. 会话不是一个选项,因为用户应该能够同时在同一浏览器的不同选项卡中使用同一页。
    3. 上下文不是一个选项,因为它在回调中不存在。
    4. 如果数据源不是linq数据上下文,则使用linq data source而不是obectdatasource不起作用,因为它不支持删除操作。
    5. 在querystring中使用唯一的id(标识正确的会话对象)是一种解决方法,但它会弄乱url。

    我在网上搜索了一段时间,我尝试了很多没有成功的事情。

    非常感谢您的帮助和建议!!

    2 回复  |  直到 16 年前
        1
  •  0
  •   Stephen M. Redd    16 年前

    可能最好的办法是在第一次加载页面时创建一个临时id。将其存储在隐藏字段中,以便viewstate知道它。

    使用某种自定义类来表示网格的数据。不要使用数据源控件,而是使用网格的数据源和数据成员属性手动绑定对象。

    使用生成的临时ID作为密钥将此对象存储在缓存中。

    在每次回发时,更新缓存中的对象并将其重新绑定到网格。

    viewstate是一种通过temp id在客户端维护标识的机制。asp.net缓存api在服务器上维护数据状态。

        2
  •  0
  •   Tillito    16 年前

    由于似乎没有更优雅的方法来解决此问题,我将以下代码实现到所有web表单都从中继承的基页类中:

    /// <summary>
    /// Set an ID to identify the correct session variable (in case there are several ones).
    /// Create this ID when it is needed for the first time.
    /// </summary>
    private string PageCallID
    {
        get
        {
            if (ViewState["PageCallID"] == null) ViewState["PageCallID"] = Guid.NewGuid().ToString("N");
            return ViewState["PageCallID"].ToString();
        }
    }
    
    /// <summary>
    /// Use a hashtable which is stored into the Session to save the in-memory
    /// objects. This helps to keep the viewstate variable at the client small.
    /// </summary>
    protected Hashtable ServerViewState
    {
        get
        {
            string strSessionKey = String.Format("CleverViewState_{0}", PageCallID);
            if (Session[strSessionKey] == null) Session[strSessionKey] = new Hashtable();
            return (Hashtable)Session[strSessionKey];
        }
    }
    

    有了这个,我们可以在任何网页上书写:

    ServerViewState["MyDataTable"] = myDataTable;
    

    而不是

    ViewState["MyDataTable"] = myDataTable;
    

    但是,此解决方案不能由静态方法调用。所以我认为这更多的是权宜之计而不是解决办法。

    如果有人知道更好的解决方法,我会感谢任何反馈!

    推荐文章