带有内存数据的GridView:在保存对象之前保存对象的位置?

时间:2010-01-08 11:06:07

标签: asp.net gridview in-memory

我的 GridView 带有 ObjectDataSource 。我想让用户创建几个对象,然后一次性保存它们。

背景:我想为食谱创建一个编辑器。配方有基本属性(如名称和原产地),它有成分(如100克黄油)我希望用户设置配方的所有属性,让他在(!!)保存到数据库之前定义其成分。还必须可以从列表中删除成分。首先保存配方然后定义配料不是一种选择。

我的问题: 在将成分保存到数据库之前,我在哪里保留成分?

这是我发现的:

  1. ViewState不是一个选项,因为ObectDataSource的GetData方法是静态的,因此无法访问视图状态。
  2. 会话不是一个选项,因为用户应该能够同时在同一浏览器的不同选项卡中使用同一页面。
  3. 上下文不是一个选项,因为它无法在回调中存活。
  4. 使用LinqDataSource而不是ObectDataSource不起作用,因为如果数据源不是linq数据上下文,它不支持删除操作。
  5. 在QueryString中使用唯一ID(以识别正确的会话对象)将是一种解决方法,但它会弄乱URL。
  6. 我一直在网上搜索一段时间,我尝试了很多事情但没有成功。

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

2 个答案:

答案 0 :(得分:0)

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

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

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

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

Viewstate是通过临时ID维护客户端身份的机制。 asp.net Cache API维护服务器上的数据状态。

答案 1 :(得分:0)

由于似乎没有更优雅的方法来解决这个问题,我将以下代码实现到我的所有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;

但是,静态方法无法调用此解决方案。所以我认为它更像是一种解决方法,而不是解决方案。

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