惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The Register - Security
The Register - Security
T
Troy Hunt's Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
C
Cybersecurity and Infrastructure Security Agency CISA
S
Securelist
G
GRAHAM CLULEY
S
Schneier on Security
S
Secure Thoughts
Know Your Adversary
Know Your Adversary
Forbes - Security
Forbes - Security
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
The Hacker News
The Hacker News
Y
Y Combinator Blog
L
LINUX DO - 最新话题
D
Docker
S
Security @ Cisco Blogs
P
Proofpoint News Feed
V
Vulnerabilities – Threatpost
博客园_首页
T
The Blog of Author Tim Ferriss
Blog — PlanetScale
Blog — PlanetScale
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
V2EX - 技术
V2EX - 技术
NISL@THU
NISL@THU
MongoDB | Blog
MongoDB | Blog
阮一峰的网络日志
阮一峰的网络日志
P
Privacy & Cybersecurity Law Blog
C
Cisco Blogs
AWS News Blog
AWS News Blog
博客园 - 司徒正美
Martin Fowler
Martin Fowler
W
WeLiveSecurity
月光博客
月光博客
博客园 - 聂微东
N
News and Events Feed by Topic
Google DeepMind News
Google DeepMind News
D
DataBreaches.Net
T
Tenable Blog
IT之家
IT之家
MyScale Blog
MyScale Blog
N
Netflix TechBlog - Medium
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - 三生石上(FineUI控件)
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
B
Blog
量子位
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
N
News and Events Feed by Topic
Vercel News
Vercel News

博客园 - 文强

sql优化的几种方式 UpdatePanel 无刷新弹出窗口 .net web 点击链接在页面指定位置显示DIV的问题 重建主键 sql 日期时间格式转换 UpdatePanel无法直接弹出窗口的解决 A标签执行JS脚本 Guid 的几种形式 iis 5.1 连接 sql 2005 CSS 垂直居中 js 获取服务器控件 js CSS VS 打包升成可自动升级的安装包 js 弹出页面传值 提示消息后跳转 spoolsv.exe 报错,无法打印 C#获取文件的当前路径 在网页中插入CSS样式表的几种方法
C# web 网页刷新时数据集的保存和应用
文强 · 2013-06-24 · via 博客园 - 文强

设计 Web 应用程序中的数据访问时,您要做出多种选择,例如与数据源通信的方式、是否在页的往返过程之间存储数据、以及如果确实要存储数据应存储在何处等。您所做的选择可以确定应用程序的运行效率及其缩放的良好程度。没有一个数据访问策略是适合于所有情况的。实际上,每一种选择都有其自身的优缺点,您将需要了解这些优缺点。

以下各节详述了您必须为 Web 窗体数据访问所做的基本设计选择。这些选择是按顺序提供的;每一种选择都建立在您前面所做出的选择的基础之上。

数据集还是直接访问和数据阅读器?

一项重要的选择是要将记录缓存在数据集中还是直接访问数据库并使用数据阅读器读取记录。对于某些数据库操作(如创建和编辑数据库结构),不能使用数据集。例如,如果想从应用程序内创建一个新的数据库表,则不能使用数据集来完成;而应执行一条数据命令。但对于一般的数据访问,常常有将记录存储在断开连接的数据集内和使用数据命令直接操作数据库两种方法可供选择。

注意   有关数据集的详细信息,请参见 数据集介绍。有关直接访问数据库的详细信息,请参见 Visual Studio 中的 DataCommand 对象介绍

每一种策略都具有适用于任何数据访问方案(而不只是 Web 窗体页)的内在优点。例如,数据集简化了对相关表的处理以及对来自完全不同的源的数据的处理。另一方面,使用数据阅读器通常会略微地提高性能和内存使用率,它消除了填充数据集的额外步骤(和内存要求),并使您能够更直接地控制所使用的语句或存储过程。有关这些方法中各方法优点大体比较的详细信息,请参见 数据访问策略建议

Web 窗体页中的数据集和数据命令

当使用 Web 窗体页时,有一些附加的因素会影响到是使用数据集还是使用数据阅读器的决定。一个重要因素就是页生命周期(由每一往返过程初始化、处理、然后放弃 Web 窗体页的过程)。如果只是想要在页上显示数据,则创建数据集、填充数据集、然后将控件绑定到数据集的这一过程可能意味着不必要的系统开销,因为该数据集将被立即放弃。在许多情况下,更为有效的方法使用数据阅读器获取数据并在运行时将控件绑定到该数据。

提示   无论决定采用何种方式从数据源获取数据,都应始终尝试将在页中使用的数据量降至最低。查询或存储过程送回的数据越多,所使用的数据库和服务器资源也就越多。

因此,在一般情况下可以认为在 Web 窗体页中,通常最好使用数据命令来执行 SQL 语句或存储过程,并使用数据阅读器来获取数据。例如,若要在DataList 命令中显示信息,可以执行一个 SQL 语句,然后将该控件绑定到一个数据阅读器。该一般性规则可能不适用于以下情况:

  • 使用相关表   数据集使您可以维护多个相关表并包括对关系和引用完整性的支持。与独立地使用对数据库执行命令的方法来获取记录相比,在数据集中处理相关记录(例如,读取父记录和相应的子记录)要简单得多。
  • 与其他进程交换数据   如果您的 Web 窗体页正在从另一个组件(例如 XML Web services)获取数据,您将几乎总是使用数据集来保留数据的本地副本。数据集自动读取和写入用来在 .NET Framework 中的各组件间进行通信的 XML 流。
  • 使用静态记录集   如果您需要重复使用同一个记录集(例如,当用户在网格中分页时)与通过每一往返过程返回到数据源相比,将那些记录填充到数据集可能效率更高。如果需要保留一组要从频繁更改的数据库中使用的特定记录,则尤其如此。

使用数据集的一个更为一般性的优点是它比直接使用数据命令更易于编程。但是,您必须基于其他的应用程序要求仔细权衡这一优点。

有关使用数据命令的详细信息,请参见 Visual Studio 中的 DataCommand 对象介绍

保存数据集还是每次重新创建?

如果您选择使用数据集,您的下一个选择就是确定是否要通过每一往返过程重新创建该数据集。有两个选择:

  • 每次处理页时,都创建数据集的实例并填充它。在完成页处理并将该页发送到浏览器后,放弃该数据集。
  • 只创建和填充一次数据集(通常是在该页第一次运行时)。然后采用某种方式保存该数据集,这种方式允许您通过以后的每次往返过程来检索它。

每次创建数据集意味着通过每一往返过程(实际上是每次用户单击页上按钮时)对数据源执行查询或存储过程。例如,您可能具有一个 Web 窗体页,用户希望在该页中逐页查看数据。如果您每次创建该数据集,则 Web 窗体页对数据源执行查询以获取下一组要显示的记录。

提示   请记住始终将数据传输量减到最小。只要可行,就使用选择条件来减少在一页上所需记录的数目。

另一方面,如果您保存和还原该数据集,您就不需要返回到源来只是获取稍多的记录。但是,保存数据集有很多缺点。其中重要的一点在于数据集在往返过程之间占用内存。例如,如果数据集非常大,它就可能占用相当多的服务器内存来存储它。如果有几个用户都创建了大型数据集,您可能很快就会耗尽可用的服务器内存。(可以选择在页中存储数据;有关详细信息,请参见下一节。)

另一个潜在的缺点在于数据集可能与数据源失去同步,因为每次用户单击按钮时您没有刷新数据集。如果使用非常易失的数据(例如清单数据),可能发现对于您的应用程序而言,通过每一往返过程重新创建数据集会更好一些。

在服务器上缓存还是在客户端上缓存?

如果您决定在往返过程之间保存数据集,则您必须决定在哪里保留它。此问题是 Web 窗体页中状态维护的标准问题之一:在往返过程间要在哪里存储您要保留的信息?有关保存值的信息,请参见 Web 窗体状态管理

有两个选择:

  • 在服务器上,以会话状态、应用程序状态或使用缓存保存数据集。
  • 在客户端上(也就是说,在页中)使用视图状态或通过将数据放置到您自己的隐藏域中来保存数据集。(视图状态也使用隐藏域实现。)

在服务器上存储数据集使用服务器资源。如果存储过多的数据(大型数据集,或者许多用户存储多个小数据集),这可能会影响服务器的性能和可缩放性。使用缓存可以部分弥补这一问题,因为在服务器需要内存或缓存的数据过期时,缓存管理器将放弃该数据集。但因为并不确保数据集处于缓存中,所以必须向页中添加逻辑以检查在缓存中该数据集是否可用;如果不可用,则必须重新创建该数据集并将副本放回到缓存中。

在页中存储数据意味着不需要服务器资源来存储数据。但是,该数据将成为此页的 HTML 流的一部分。如果数据集较大,可能会显著影响将该页加载到用户的浏览器以及将该页回发到服务器所花的时间。有关以视图状态保存数据的详细信息,请参见 使用视图状态保存 Web 窗体页值

提示   通过只用您所需的记录填充数据集,始终尽量将数据集的大小保持为最小。

无论您决定在哪里存储数据集,都必须向页上添加逻辑以在适当的时间保存和还原该数据集。下面的示例说明以会话状态存储和还原数据集的典型方式。数据集 dsCustomers1 是数据集类 dsCustomers 的实例。请注意,该数据集在会话状态中作为 Object 类型存储。当从会话状态还原该数据集时,必须将其从 Object 转换回数据集类。

  1. 'Visual Basic
  2. Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  3.    If Page.IsPostBack Then
  4.       dsCustomers1 = CType(Session("myDsCustomers"), dsCustomers)
  5.    Else
  6.       If Session("myDsCustomers") Is Nothing Then
  7.          OleDbDataAdapter1.Fill(dsCustomers1)
  8.          Session("myDsCustomers") = dsCustomers1
  9.       End If
  10.    End If
  11. End Sub
  12.  
  13. //C#
  14. private void Page_Load(object sender, System.EventArgs e)
  15. {
  16.    // Put user code to initialize the page here
  17.     if (Page.IsPostBack) 
  18.     {
  19.         dsCustomers1 = (dsCustomers) Session["myDsCustomers"];
  20.     }
  21.     else
  22.     {
  23.         if (Session["myDsCustomers"] == null
  24.         {
  25.             oleDbDataAdapter1.Fill(dsCustomers1);
  26.             Session["myDsCustomers"] = dsCustomers1;
  27.         }
  28.     }
  29. }