【问题标题】:How to save state across requests for an entity in ASP.NET without saving to database using EntityFramework?如何在 ASP.NET 中跨实体请求保存状态而不使用 EntityFramework 保存到数据库?
【发布时间】:2012-12-10 13:58:42
【问题描述】:

我正在开发一个 CRUD ASP.NET WebForms Web 应用程序,该应用程序由用户填写数据的几个页面组成。我的客户不想将实体存储在页面之间的数据库中,直到用户单击最后一页上的完成(出于各种原因)。有哪些选项可以在页面之间传播填充的数据,哪个最不坏?从我的阅读中我看到可以使用 ViewState 和 Server.Transfer。任何其他选项,最好使用更少的魔法字符串和更多类型安全的数据绑定到实体对象?

【问题讨论】:

  • 最好的选择是将这些临时数据保存在数据库中。相反,这样做真的没有任何价值。将其存储在内存中会降低应用程序的可扩展性。
  • @StevenVandeWeyer - 我很确定有更好的选择
  • 本讨论中提到的所有选项都归结为客户端或服务器端技术。客户端技术增加了您的带宽使用。从服务器技术来看,很明显您需要投入一些服务器资源。如果我要选择使用哪些服务器资源,我通常更喜欢保留在 DB 中。大多数数据库以非常负责任和可扩展的方式管理服务器资源。也可能有一个特定的原因不保留在数据库中。可能是他们希望保持数据源“干净”这些数据。一个新的数据库实例可能是一个很好的反驳。

标签: c# asp.net entity-framework webforms


【解决方案1】:

使用ViewState 将显着增加您通过网络发送的数据量,因为所有Viewstate 数据都被序列化为表单中的隐藏输入,因此当您添加对象时,您的HTTP 请求-响应将进行显着增长。

这真的没有灵丹妙药。如果您的数据不太复杂,我会将值存储在查询字符串中。如果你的对象变得复杂和庞大,并且你想保持类型安全,我会使用Session,但记得自己清理!

另一种选择是使用 MVC 范例并使用隐藏输入以它自身的形式存储值。这意味着如果用户中途出错,您无需担心清理会话,但它也可以保持查询字符串干净。

认为这就是你所有的选择,querystringviewstate(don't do it)session隐藏变量 em>。

好的,因此您必须对数据进行序列化,这样您就无法保留上下文。这是不可序列化的,所以以上是您的选择:

各有优劣,

  • Viewstate(低效但易于使用)
  • 查询字符串(对大型数据集有效但不实用且可编辑)
  • 会话(增加服务器负载并需要清理,但允许您仅在服务器上保留数据)
  • 隐藏变量(对用户隐藏但比视图状态更有效,需要为每个属性提供大量隐藏输入)

任君挑选!

【讨论】:

  • 视图状态可以很好地用于表单,特别是如果应用程序将仅是 Intranet。另一方面,查询字符串有可能被操纵。在查询字符串中传递将用作表单输入数据的任何内容都是危险的。隐藏字段将使用与会话状态相同的开销。所有这些并没有真正解决跨页面更改保存实体对象而不实际保存到数据库的问题。
  • viewState 将对象状态序列化为二进制格式,因此将类型等编码到隐藏输入中,然后需要对其进行序列化,然后对请求/响应的每一侧进行解封,从而增加基于仅隐藏输入。我从来没有建议不能操纵查询字符串。请注意,您在没有建议任何更好的选择的情况下标记了我???
  • 另外说,“这是一个 Intranet,所以让我们忽略所有性能指标”是非常愚蠢的。仅仅因为您在 Gb 以太网上并不意味着您不应该尽可能地优化您的代码。
  • OP 在哪里专门询问有关持久化实体上下文的问题?虽然可能是可能的,但它非常危险。
  • 此答案中的所有选项都有效,但您也可以添加Cache 以完成。
【解决方案2】:

您可以将客户端应用程序中使用的所有对象存储在Session 中,然后当用户单击完成时,您将这些对象发送到服务/方法,您可以将它们转换为实体,然后将它们提交到数据库。

【讨论】:

  • 使用会话存储实体上下文可能很危险。
  • @Chad:我从来没有说过要在会话中存储上下文。我只是指包含数据的对象——理想情况下是数据合同或类似的东西,然后将被转换为实体。
  • @Chad:我已经更改了答案以避免任何误解,我希望现在已经足够清楚了
  • 该操作专门要求在没有 savechanges() 调用的情况下更改实体上下文中的数据。您建议使用 Session 来存储对象。您可以将上下文存储在会话中,但如果这样做,您最好有一些代码来处理由此产生的问题。
  • @Chad:让我再说一遍:我从来没有提到在会话中存储上下文,你是一个人一遍又一遍地说。也许我没有很好地理解这个问题,但我的理解是他希望所有数据只有在用户按下“完成”按钮时才提交到数据库:“我的客户不想存储实体在页面之间的数据库中,直到用户单击最后一页上的完成(出于各种原因)
【解决方案3】:

使用 MemCached。
互联网上有大量示例。
试试这个:
Implementing Distributed Caching using Memcached

【讨论】:

  • 我看不出缓存在这种情况下会有什么帮助。
  • 阅读链接我不明白 MemCached 的工作原理或存储实体上下文对象的工作原理。
  • Memcache 是 Session 的完美替代品。内存数据存储速度快,如前所述,您无法存储实体上下文,因此这无关紧要。
【解决方案4】:

不确定我做错了什么,但我的 ASP Web API 控制器没有可用的会话状态?我这样做了: (1) 转到定义了该静态类的 WebApiConfig 文件,因为我想要在调用我的控制器之前运行一次的一些代码块。在那里,我添加了一个公共静态 List 变量 myList。 (2) 然后在 Register 方法中,我完成了该列表的定义。 (3) 现在在我的控制器中,我有一个持久的(只要我不重新启动应用程序)列表,我也可以读写。

public static class WebApiConfig
{
    public static List<Note> myList;
    public static void Register(HttpConfiguration config)
    {
        myList = new List<Note>();
        myList.Add(new Note { Id = "1", Subject = "Wake up", Details = "Set alarm of 7:00 am and get out of bed." });
        myList.Add(new Note { Id = "2", Subject = "Eat breakfast", Details = "Eat a healthy breakfast." });
        myList.Add(new Note { Id = "3", Subject = "Go to work", Details = "Get to work before 9:00 am." });

        // Web API configuration and services

        // Web API routes
        config.MapHttpAttributeRoutes();
         ... more code

然后在Controller中

public Note Save(Note newNote)
{
    WebApiConfig.myList.Add(newNote);
    return newNote;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-14
    • 1970-01-01
    • 2020-09-22
    • 1970-01-01
    • 1970-01-01
    • 2020-04-18
    相关资源
    最近更新 更多