野原鑫之助 | 发布时间: 2009.9.22 08:17
1. 数据库访问性能优化
数据库的连接和关闭
访问数据库资源需要创建连接、打开连接和关闭连接几个操作。这些过程需要多次与数据库交换信息以通过身份验证,比较耗费服务器资源。ASP.NET中提供了连接池(Connection Pool)改善打开和关闭数据库对性能的影响。系统将用户的数据库连接放在连接池中,需要时取出,关闭时收回连接,等待下一次的连接请求。连接池的大小是有限的,如果在连接池达到最大限度后仍要求创建连接,必然大大影响性能。因此,在建立数据库连接后只有在真正需要操作时才打开连接,使用完毕后马上关闭,从而尽量减少数据库连接打开的时间,避免出现超出连接限制的情况。
使用存储过程
存储过程是存储在服务器上的一组预编译的SQL语句,类似于DOS系统中的批处理文件。存储过程具有对数据库立即访问的功能,信息处理极为迅速。使用存储过程可以避免对命令的多次编译,在执行一次后其执行规划就驻留在高速缓存中,以后需要时只需直接调用缓存中的二进制代码即可。另外,存储过程在服务器端运行,独立于ASP.NET程序,便于修改,最重要的是它可以减少数据库操作语句在网络中的传输。
优化查询语句
ASP.NET中ADO连接消耗的资源相当大,SQL语句运行的时间越长,占用系统资源的时间也越长。因此,尽量使用优化过的SQL语句以减少执行时间。比如,不在查询语句中包含子查询语句,充分利用索引等。
2. 字符串操作性能优化
使用值类型的ToString方法
在连接字符串时,经常使用"+"号直接将数字添加到字符串中。这种方法虽然简单,也可以得到正确结果,但是由于涉及到不同的数据类型,数字需要通过装箱操作转化为引用类型才可以添加到字符串中。但是装箱操作对性能影响较大,因为在进行这类处理时,将在托管堆中分配一个新的对象,原有的值复制到新创建的对象中。使用值类型的ToString方法可以避免装箱操作,从而提高应用程序性能。
运用StringBuilder类
String类对象是不可改变的,对于String对象的重新赋值在本质上是重新创建了一个String对象并将新值赋予该对象,其方法ToString对性能的提高并非很显著。在处理字符串时,最好使用StringBuilder类,其.NET 命名空间是System.Text。该类并非创建新的对象,而是通过Append,Remove,Insert等方法直接对字符串进行操作,通过ToString方法返回操作结果。 其定义及操作语句如下所示:
int num;
System.Text.StringBuilder str = new System.Text.StringBuilder(); //创建字符串
str.Append(num.ToString()); //添加数值num
Response.Write(str.ToString); //显示操作结果
3. 优化 Web 服务器计算机和特定应用程序的配置文件以符合您的特定需要
默认情况下,ASP.NET 配置被设置成启用最广泛的功能并尽量适应最常见的方案。因此,应用程序开发人员可以根据应用程序所使用的功能,优化和更改其中的某些配置,以提高应用程序的性能。下面的列表是您应该考虑的一些选项。
仅对需要的应用程序启用身份验证。
默认情况下,身份验证模式为 Windows,或集成 NTLM。大多数情况下,对于需要身份验证的应用程序,最好在 Machine.config 文件中禁用身份验证,并在 Web.config 文件中启用身份验证。根据适当的请求和响应编码设置来配置应用程序。ASP.NET 默认编码格式为 UTF-8。如果您的应用程序为严格的 ASCII,请配置应用程序使用 ASCII 以获得稍许的性能提高。
考虑对应用程序禁用 AutoEventWireup。
在 Machine.config 文件中将 AutoEventWireup 属性设置为 false,意味着页面不将方法名与事件进行匹配和将两者挂钩(例如 Page_Load)。如果页面开发人员要使用这些事件,需要在基类中重写这些方法(例如,需要为页面加载事件重写 Page.OnLoad,而不是使用 Page_Load 方法)。如果禁用 AutoEventWireup,页面将通过将事件连接留给页面作者而不是自动执行它,获得稍许的性能提升。
从请求处理管线中移除不用的模块。
默认情况下,服务器计算机的 Machine.config 文件中 节点的所有功能均保留为激活。根据应用程序所使用的功能,您可以从请求管线中移除不用的模块以获得稍许的性能提升。检查每个模块及其功能,并按您的需要自定义它。例如,如果您在应用程序中不使用会话状态和输出缓存,则可以从 列表中移除它们,以便请求在不执行其他有意义的处理时,不必执行每个模块的进入和离开代码。
4. 一定要禁用调试模式
在部署生产应用程序或进行任何性能测量之前,始终记住禁用调试模式。如果启用了调试模式,应用程序的性能可能受到非常大的影响。
5. 对于广泛依赖外部资源的应用程序,请考虑在多处理器计算机上启用网络园艺
ASP.NET 进程模型帮助启用多处理器计算机上的可缩放性,将工作分发给多个进程(每个CPU一个),并且每个进程都将处理器关系设置为其 CPU。此技术称为网络园艺。如果应用程序使用较慢的数据库服务器或调用具有外部依赖项的 COM 对象(这里只是提及两种可能性),则为您的应用程序启用网络园艺是有益的。但是,在决定启用网络园艺之前,您应该测试应用程序在网络园中的执行情况。
6. 只要可能,就缓存数据和页输出
ASP.NET 提供了一些简单的机制,它们会在不需要为每个页请求动态计算页输出或数据时缓存这些页输出或数据。另外,通过设计要进行缓存的页和数据请求(特别是在站点中预期将有较大通讯量的区域),可以优化这些页的性能。与 .NET Framework 的任何 Web 窗体功能相比,适当地使用缓存可以更好的提高站点的性能,有时这种提高是超数量级的。使用 ASP.NET 缓存机制有两点需要注意。首先,不要缓存太多项。缓存每个项均有开销,特别是在内存使用方面。不要缓存容易重新计算和很少使用的项。其次,给缓存的项分配的有效期不要太短。很快到期的项会导致缓存中不必要的周转,并且经常导致更多的代码清除和垃圾回收工作。若关心此问题,请监视与 ASP.NET Applications 性能对象关联的 Cache Total Turnover Rate 性能计数器。高周转率可能说明存在问题,特别是当项在到期前被移除时。这也称作内存压力。
7. 选择适合页面或应用程序的数据查看机制
根据您选择在 Web 窗体页显示数据的方式,在便利和性能之间常常存在着重要的权衡。例如,DataGrid Web 服务器控件可能是一种显示数据的方便快捷的方法,但就性能而言它的开销常常是最大的。在某些简单的情况下,您通过生成适当的 HTML 自己呈现数据可能很有效,但是自定义和浏览器定向会很快抵销所获得的额外功效。Repeater Web 服务器控件是便利和性能的折衷。它高效、可自定义且可编程。
8. 将 SqlDataReader 类用于快速只进数据游标
SqlDataReader 类提供了一种读取从 SQL Server 数据库检索的只进数据流的方法。如果当创建 ASP.NET 应用程序时出现允许您使用它的情况,则 SqlDataReader 类提供比 DataSet 类更高的性能。情况之所以这样,是因为 SqlDataReader 使用 SQL Server 的本机网络数据传输格式从数据库连接直接读取数据。另外,SqlDataReader 类实现 IEnumerable 接口,该接口也允许您将数据绑定到服务器控件。有关更多信息,请参见 SqlDataReader 类。有关 ASP.NET 如何访问数据的信息,请参见通过 ASP.NET 访问数据。
9. 将 SQL Server 存储过程用于数据访问
在 .NET Framework 提供的所有数据访问方法中,基于 SQL Server 的数据访问是生成高性能、可缩放 Web 应用程序的推荐选择。使用托管 SQL Server 提供程序时,可通过使用编译的存储过程而不是特殊查询获得额外的性能提高。
10. 避免单线程单元 (STA) COM 组件
默认情况下,ASP.NET 不允许任何 STA COM 组件在页面内运行。若要运行它们,必须在 .aspx 文件内将 ASPCompat=true 属性包含在 @ Page 指令中。这样就将执行用的线程池切换到 STA 线程池,而且使 HttpContext 和其他内置对象可用于 COM 对象。前者也是一种性能优化,因为它避免了将多线程单元 (MTA) 封送到 STA 线程的任何调用。使用 STA COM 组件可能大大损害性能,应尽量避免。若必须使用 STA COM 组件,如在任何 interop 方案中,则应在执行期间进行大量调用并在每次调用期间发送尽可能多的信息。另外,小心不要在构造页面期间创建任何 STA COM 组件。例如下面的代码中,在页面构造时将实例化由某个线程创建的 MySTAComponent,而该线程并不是将运行页面的 STA 线程。这可能对性能有不利影响,因为要构造页面就必须完成 MTA 和 STA 线程之间的封送处理。
<%@ Page Language="VB" ASPCompat="true" %>
<script. runat=server>
Dim myComp as new MySTAComponent()
Public Sub Page_Load()
myComp.Name = "Bob"
End Sub
</script>
<html>
<%
Response.Write(myComp.SayHello)
%> Response.Write(myComp.SayHello)
%>
</html>
首选机制是推迟对象的创建,直到以后在 STA 线程下执行上述代码,如下面的例子所示。
<%@ Page Language="VB" ASPCompat="true" %>
<script. runat=server>
Dim myComp
Public Sub Page_Load()
myComp = new MySTAComponent()
myComp.Name = "Bob"
End Sub
</script>
<html>
<%
Response.Write(myComp.SayHello)
%> Response.Write(myComp.SayHello)
%>
</html>
推荐的做法是在需要时或者在 Page_Load 方法中构造任何 COM 组件和外部资源。永远不要将任何 STA COM 组件存储在可以由构造它的线程以外的其他线程访问的共享资源里。这类资源包括像缓存和会话状态这样的资源。即使 STA 线程调用 STA COM 组件,也只有构造此 STA COM 组件的线程能够实际为该调用服务,而这要求封送处理对创建者线程的调用。此封送处理可能产生重大的性能损失和可伸缩性问题。在这种情况下,请研究一下使 COM 组件成为 MTA COM 组件的可能性,或者更好的办法是迁移代码以使对象成为托管对象。
11. 将调用密集型的 COM 组件迁移到托管代码
.NET Framework 提供了一个简单的方法与传统的 COM 组件进行交互。其优点是可以在保留现有投资的同时利用新的平台。但是在某些情况下,保留旧组件的性能开销使得将组件迁移到托管代码是值得的。每一情况都是不一样的,决定是否需要迁移组件的最好方法是对 Web 站点运行性能测量。建议您研究一下如何将需要大量调用以进行交互的任何COM 组件迁移到托管代码。许多情况下不可能将旧式组件迁移到托管代码,特别是在最初迁移 Web 应用程序时。在这种情况下,最大的性能障碍之一是将数据从非托管环境封送到托管环境。因此,在交互操作中,请在任何一端执行尽可能多的任务,然后进行一个大调用而不是一系列小调用。例如,公共语言运行库中的所有字符串都是 Unicode 的,所以应在调用托管代码之前将组件中的所有字符串转换成 Unicode 格式。另外,一处理完任何 COM 对象或本机资源就释放它们。这样,其他请求就能够使用它们,并且最大限度地减少了因稍后请求垃圾回收器释放它们所引起的性能问题。
12. 在 Visual Basic .NET 或 JScript. 代码中使用早期绑定
以往,开发人员喜欢使用 Visual Basic、VBScript. 和 JScript. 的原因之一就是它们所谓“无类型”的性质。变量不需要显式类型声明,并能够简单地通过使用来创建它们。当从一个类型到另一个类型进行分配时,转换将自动执行。不过,这种便利会大大损害应用程序的性能。Visual Basic 现在通过使用 Option Strict 编译器指令来支持类型安全编程。为了向后兼容,默认情况下,ASP.NET 不启用该选项。但是,为了得到最佳性能,强烈建议在页中启用该选项。若要启用 Option Strict,请将 Strict 属性包括在 @ Page 指令中,或者,对于用户控件,请将该属性包括在 @ Control 指令中。下面的示例演示了如何设置该属性,并进行了四个变量调用以显示使用该属性是如何导致编译器错误的。
<%@ Page Language="VB" Strict="true" %>
<%
Dim B
Dim C As String
' This will cause a compiler error.
A = "Hello"
' This will cause a compiler error.
B = "World"
' This will not cause a compiler error.
C = "!!!!!!"
' But this will cause a compiler error.
C = 0
%> Dim B
Dim C As String
' This will cause a compiler error.
A = "Hello"
' This will cause a compiler error.
B = "World"
' This will not cause a compiler error.
C = "!!!!!!"
' But this will cause a compiler error.
C = 0
%> JScript. .NET 也支持无类型编程,但它不提供强制早期绑定的编译器指令。若发生下面任何一种情况,则变量是晚期绑定的:被显式声明为 Object,是无类型声明的类的字段,是无显式类型声明的专用函数或方法成员,并且无法从其使用推断出类型。 最后一个差别比较复杂,因为如果 JScript. .NET 编译器可以根据变量的使用情况推断出类型,它就会进行优化。在下面的示例中,变量 A 是早期绑定的,但变量 B 是晚期绑定的。
var A;
var B;
A = "Hello";
B = "World";
B = 0; 为了获得最佳的性能,当声明 JScript. .NET 变量时,请为其分配一个类型。例如,var A : String。
13. 使请求管线内的所有模块尽可能高效
请求管线内的所有模块在每次请求中都有机会被运行。因此,当请求进入和离开模块时快速地触发代码至关重要,特别是在不使用模块功能的代码路径里。分别在使用及不使用模块和配置文件时执行吞吐量测试,对确定这些方法的执行速度非常有用。
转摘自:http://www.chinaz.com/Program/.NET/051W633R009.html
2555c152-e322-48f7-9381-12255c6838ef|1|2.0
野原鑫之助 | 发布时间: 2009.9.17 23:56
在ASP.NET中有时候需要点击一个文件的链接将其下载而不是直接在浏览其中打开该文件,则可以采用如下处理:
if (!IsPostBack)
{
string fileName = Request.QueryString["FileName"];
if (fileName != null && fileName.Trim() != "")
{
string filePath = System.Configuration.ConfigurationManager.AppSettings["ArticleUploadPath"];
if (filePath == null || filePath.Trim() == "")
filePath = "~/UploadFiles/";
filePath = System.IO.Path.Combine(filePath, "Articles/"+fileName);
Response.Clear();
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(Server.MapPath(filePath)));
Response.WriteFile(filePath);
Response.End();
}
}
//中文名文件的时候需要如上面的HttpUtility.UrlEncode
转摘自:http://www.cnblogs.com/MeChecksV/articles/1486020.html
4e7b5def-ac84-4d0d-8c68-c0693679c26c|0|.0
野原鑫之助 | 发布时间: 2009.8.4 11:51
在做Asp.Net开发的时候,经常会遇到页面乱码的问题,下面是在网上收集的相关资料,请大家参考:
解决的方法一般有3种:
1.设置web.config文件
<system.web>
......
<globalization requestEncoding="gb2312" responseEncoding="gb2312" culture="zh-CN" fileEncoding="gb2312" />
......
</system.web>
2.传递中文之前,将要传递的中文参数进行编码,在接收时再进行解码。
>> 进行传递
string Name = "中文参数";
Response.Redirect("B.aspx?Name="+Server.UrlEncode(Name)) ;
>> 进行接收
string Name = Request.QueryString["Name"];
Response.Write(Server.UrlDecode(Name)) ;
3.如果是从 .HTML 文件向 .Aspx 文件进行传递中文参数的话(即不从后台用 Redirect()方法进行 Url 转换)。一样要将传递的中文参数进行编码,在接收时再进行解码。
>> 进行传递
<script language="JavaScript">
function GoUrl()
{
var Name = "中文参数";
location.href = "B.aspx?Name="+escape(Name) ;
}
<body onclick="GoUrl()">
>> 进行接收
string Name = Request.QueryString["Name"];
Response.Write(Server.UrlDecode(Name)) ;
总结:
一般来说。设置web.config文件就可以了。但是如果你用 JavaScript 调用 webservice 方法的话(往webservice里面传递中文参数)。设置 web.config 文件好象无效。
或用
Response.Redirect("test1.aspx?111="+System.Web.HttpUtility.UrlEncode("中华人明共和国")) ;
//建议使用最后如果是从其他的页面获取中文参数没有乱码,那就更简单了
string message ="http://localhost/Test/test1.aspx?111="+System.Web.HttpUtility.UrlEncode("中华人明共和国");
http:
//你要获取某个页面的返回值的地址"
//发送请求
HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(message) ;
//接受请求
HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse() ;
Stream receiveStream = myHttpWebResponse.GetResponseStream() ;
StreamReader readStream = new StreamReader(receiveStream, System.Text.Encoding.GetEncoding("GB2312")) ;
//此为要取页面的返回值输出的返回结果
returnValue = readStream.ReadToEnd();
转摘自:http://hi.baidu.com/miracletan2008/blog/item/81edad988179ce016f068c28.html
0dec25d2-a115-4f75-be82-3d970c98b69f|1|5.0
野原鑫之助 | 发布时间: 2009.8.4 11:49
1 设计处理图片的HttpHandler处理程序
添加一个“一般处理程序”模板,修改其中的代码,如下:
public void ProcessRequest(HttpContext context){
//判断是否是本地引用,如果是则给客户端返回正确的图片,这里的判断用到了http请求中所记录的页信息
//如果是网站,可将“localhost”修改为网站地址
if(context.Request.UrlReferrer.Host=="localhost"){
//设置客户端缓冲文件过期时间为0,即立即过期
context.Response.Expires=0;
//清空服务器端为此会话开辟的输出缓存
context.Response.Clear();
//获得文件类型
context.Response.ContentType="image/jpg";
//将请求文件写如到输出缓存中
context.Response.WriteFile(context.Request.PhysicalPath);
context.Response.End();
}
//如果不是本地引用,则属于盗链引用,给客户端返回错误的图片
else{
context.Response.Expires=0;
context.Response.Clear();
context.Response.ContentType="image/jpg";
//将报告错误的图片文件写如到输出缓存中
context.Response.WriteFile(context.Request.PhysicalApplicationPath+"error.jpg");
context.Response.End();
}
}
public bool IsReusable{
get{
return true;
}
}
将上述代码复制到一个类文件中,在App_Code目录下
在应用配置中注册HttpHandler,打开“web.config”,在“system.web”节点下,添加处理程序的注册信息,如下:
<httpHandlers>
<add verb="*" path="*.jpg" type="Handler" />
</httpHandlers>
在IIS中配置图片的特殊处理程序
虽然在应用程序中已经配置好了处理“.jpg”文件的程序,但浏览器的请求是直接发送给IIS的,而不是给应用程序,所以还需要在IIS中配置,使得当浏览器请求“.jpg”文件类型时,IIS可以交由ASP.NET处理,配置步骤如下:
(1) 打开系统自带的“Internet信息服务”,在左侧目录树中,右击“网站”节点。在弹出的快捷菜单中,选中“属性”菜单命令,打开网站的属性对话框,切换到“主目录”选项卡界面,单击“配置”按钮,打开“应用程序配置”对话框。“应用程序映射”列表框中,罗列出了IIS所有能够处理的文件格式,以及这些格式对应的处理程序。在此列表框中选中“.aspx”条目,单击“编辑”按钮,打开“添加/编辑应用程序扩展名映射”对话框,在“可执行文件”文本框中的内容为“C:\windows\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll”。为了让IIS能够将“JPG”格式的文件,正确映射到前面编写的“HttpHandler”处理中,需要为其加载“aspnet_isapi.dll”文件。单击“添加”按钮,打开空白的“添加/编辑应用程序扩展名映射”对话框,在“扩展名”文本框中输入“.jpg”。在“可执行文件”文本框中输入“C:\windows\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll”,单击“确定”,返回到“应用程序配置”对话框,单击“确定”按钮,返回到“网站属性”对话框,在单击其中的“确定”按钮。这样一个防止盗用“.jpg”图片的解决方案就完成了。
防盗链下载实例
以“.rar”压缩包格式为例,实现对非法下载的处理。
在页面中添加一个“LinkButton”控件,并修改其属性“PostBackUrl”为“~/Files/资源文件.rar”。
在类中添加处理请求的方法和返回属性。当请求来自于本站点时,不做任何处理,当请求来自其他站点时,将页面导航到本站的下载页(方法同上),具体代码如下。
public void ProcessRequest(HttpContext context){
if(context.Request.UrlReferrer.Host=="localhost"){
//允许用户直接下载,不做任何操作
}
else{
//将请求转到特殊处理页,以实现下载功能
HttpResponse response=context.Response;
//导航到下载页面
response.Redirect(context.Request.PhysicalApplicationPath+"Download.aspx");
}
}
//返回是否执行此处理程序
public bool IsReusable{
get{
return true;
}
}
<httpHandlers>
<add verb="*" path="Files/*.rar" type="FileHandler" />
</httpHandlers>
打开IIS,添加应用程序的扩展,扩展名为“.rar”,同上。
转摘自:http://hi.baidu.com/sevenxue2008/blog/item/74f0262694fd0a05908f9d7e.html
02e520a9-be61-4e98-9040-2189669b4177|1|5.0
野原鑫之助 | 发布时间: 2009.7.24 23:07
在.NET环境下使用C#防止SQL注入式攻击,我们的解决方式是:
1、首先在UI录入时,要控制数据的类型和长度、防止SQL注入式攻击,系统提供检测注入式攻击的函数,一旦检测出注入式攻击,该数据即不能提交;
2、业务逻辑层控制,通过在方法内部将SQL关键字用一定的方法屏蔽掉,然后检查数据长度,保证提交SQL时,不会有SQL数据库注入式攻击代码;但是这样处理后,要求UI输出时将屏蔽的字符还原。因此系统提供屏蔽字符 的函数和还原字符的函数。
3、在数据访问层,绝大多数采用存储过程访问数据,调用时以存储过程参数的方式访问,也会很好的防止注入式攻击。
转摘自:http://www.chinaz.com/Program/.NET/0H3Sa62009.html
a74c38fb-8d2e-4dad-92e0-16e564edfd34|0|.0
野原鑫之助 | 发布时间: 2009.7.19 14:12
网上查了很多方法,都不太好使,不如自己写一个,思路就是把按钮按下时用Javascript在客户端把按钮下一次的onclick事件改为return false; 这样在服务器端页面重新送回客户端之前,再次点击按钮都不会Post到服务端。同时将按钮的style改为一行字的样子,光标也变成沙漏状。当服务端页面重新产生后Button又会回到初始状态。该方法对于F5刷新还不能防范,只是简单封闭了F5的按键,为了防止刷新时再次提交可以在页面返回前将一些TextBox控件清空,这样就可以判断如果该TextBox为空则不再进行后续操作(如写库)。 或是后台操作成功后跳转到另一个页面以防止恶意刷新。主要是考虑在企业内网使用,不是为了防黑客,所以不是非常严格。
以下为引用的内容:《br/> <html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>禁止多次提交网页测试</title>
<style type="text/css">
.disable
{
border-style:none;
border-width: thin;
background-color:Transparent;
color: #CCCCCC;
cursor:wait;
}
</style>
<script type="text/javascript" language="javascript">
function DisableButton()
{
document.getElementById("Button2").className = "disable";
document.getElementById("Button2").value = '正在提交.';
document.getElementById("Button2").onclick=Function("return false;");
return true;
}
document.onkeydown=mykeydown;
function mykeydown()
{
if(event.keyCode==116) //屏蔽F5刷新键
{
window.event.keyCode=0;
return false;
}
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
输入一些内容<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<br />
<asp:ListBox ID="ListBox1" runat="server" Height="77px" Width="332px">
</asp:ListBox><br />
<asp:Button ID="Button2" runat="server" Text="OK" Width="77px"
onclick="Button2_Click" />
</div>
</form>
</body>
</html>
|
转摘自:http://www.chinaz.com/Program/.NET/11264D292008.html
09ea28fc-bf80-4281-8cd0-bc750e806649|3|3.0
野原鑫之助 | 发布时间: 2009.7.19 14:02
ADO.NET提供了多种对象模型,比较典型的以下有五种,它们全部归类在System.Data.SqlClient名称空间下。
一、SqlConnection对象
ADO.NET使用SqlConnection对象与SQL Server进行连接。连接字符串的常用形式有两种:
1.使用Windows集成安全身份认证,例如:string connectionString ="IntegratedSecurity=SSPI;Database=MyDatabase.mdf;Server=localhost;";
或:string connectionString = "Initial Catalog= MyDataBase; Data Source=localhost;Integrated Security=SSPI;"
2.在连接字符串中指定服务器名、用户id、用户口令、数据库名等信息。例如:string connectionString = "server=localhost; uid=sa; pwd=123; database=MyDatabase.mdf";
然后通过连接字符串直接创建SqlConnection对象,如SqlConnection conn = new SqlConnection(connectionString);
二、SqlCommand对象
在ADO.NET中,有两种操作数据库的方式:
1.无连接的方式;
2.保持连接的方式。
不论采用哪种方式,都可以通过SqlCommand对象提供的方法传递对数据库操作的命令,并返回命令执行的结果。
在保持连接的方式下操作数据库的一般步骤为:
1.创建SqlConnection的实例;
2.创建SqlCommand的实例;
3.打开连接;
4.执行命令;
5.关闭连接。
SqlCommand对象提供了多种完成对数据库操作的方法。常用有:
1.ExecuteNonQuery
该方法执行SQL语句的结果,但不返回命令执行的表数据,仅返回操作所影响的行数。
2.ExecuteReader
ExecuteReader方法提供了只向前的、顺序的快速读取数据库中数据的方法。该方法根据提供的SELECT语句,返回一个可以顺序读取的SqlDataReader对象,编程者可以使用Read方法循环依次读取每个记录中各字段(列)的内容。
3.ExecuteScaler()
该方法用于执行SELECT查询,得到的返回结果为一个值的情况,比如使用count函数求表中记录个数或者使用sum函数求和等。
三、SqlDataAdapter对象
SqlDataAdapter对象通过无连接的方式完成数据库和本地DataSet之间的交互。使用这种方式操作数据库的一般步骤为:
1.创建SqlConnection的实例;
2.创建SqlDataAdapter的实例,需要的话,根据select语句生成其他SQL语句;
3.创建DataSet的实例;
4.使用Fill方法将数据库中的表填充到DataSet的表中;
5.利用DataGridView或者其他控件对象编辑或显示数据;
6.需要的话,使用Update方法更新数据库。
SqlDataAdapter对象通过SelectCommand、InsertCommand、UpdateCommand和DeleteCommand属性为后台数据库提供对应的操作命令,并传递需要的参数。一般情况下,只需要提供SELECT语句和连接字符串创建SqlDataAdapter对象,然后利用SqlCommandBuilder对象生成InsertCommand、UpdateCommand和DeleteCommand属性。
四、DataTable对象
ADO.NET可以在与数据库断开连接的方式下通过DataSet或DataTable对象进行数据处理,当需要更新数据时才重新与数据源进行连接,并更新数据源。DataTable对象表示保存在本机内存中的表,它提供了对表中行列数据对象的各种操作。可以直接将数据从数据库填充到DataTable对象中,也可以将DataTable对象添加到现有的DataSet对象中。在断开连接的方式下,DataSet对象提供了和关系数据库一样的关系数据模型,代码中可以直接访问DataSet对象中的DataTable对象,也可以添加、删除DataTable对象。
1. 创建DataTable对象
可以通过以下两种方式创建DataTable对象:
1) 通过DataTable类的构造函数创建DataTable对象,例如:
DataTable table = new DataTable();
2) 通过DataSet的Tables对象的Add方法创建DataTable对象,例如:
DataSet dataset = new DataSet();
DataTable table = dataset.Tables.Add("MyTableName");
2. 在DataTable对象中添加列
在DataTable对象中添加列的最常用的方法是通过DataTable对象的Column属性中的Add方法。添加后的每一列都是一个DataColumn对象。
3. 设置DataTable对象的主键
关系数据库中的表一般都有一个主键,用来惟一标识表中的每一行记录。通过DataTable对象的PrimaryKey属性可以设置Datatable的主键。主键可以是一个或者多个DataColumn对象组成的数组。例如:
DataColumn[] key = new DataColumn[1];//dt是一个DataTable对象
key[0] = dt.Columns[0];
dt.PrimaryKey = key;
4. 在DataTable对象中创建行
DataTable对象的每一行都是一个DataRow对象,所以创建行时可以先利用DataTable对象的NewRow方法创建一个DataRow对象,并设置新行中各列的数据,然后利用Add方法将DataRow对象添加到表中
5. 将SQL Server数据库中的表填充到DataTable中
除了可以直接创建DataTable对象的行列信息外,也可以通过DateAdapter对象的Fill方法将SQL Server数据库中的表填充到DataTable对象中。
五、DataSet对象
1. 创建DataSet对象
使用创建的DataSet对象可以完成各种数据操作,利用向导生成的数据库数据源是一个强类型的DataSet以及一对或多对强类型的DataTable和TableAdapter的组合。类型化的DataSet是一个生成的类,是从.NET Framework的一般DataSet类衍生来的,但提供了已定义的架构以及特定于该架构的属性和方法。同时,对于DataSet中的每个表,还生成了特定于该DataSet的附加衍生类,而且每个类都为相关的表提供了特定的架构、属性和方法。
当然,也可以直接创建一般的DataSet对象,例如:
DataSet myDataset = new DataSet();
2. 填充DataSet对象
创建DataSet后,就可以使用SqlDataAdapter对象把数据导入到DataSet对象中,比如通过Fill方法将数据填充到DataSet中的某个表中。
转摘自:http://www.chinaz.com/Program/.NET/0511K2A2009.html
41cef3e3-1f3b-4b3c-88bf-8de38e029321|0|.0
野原鑫之助 | 发布时间: 2009.7.19 13:55
最近在用asp.net ,在将绑定数据到DropDownList。时抛出了一个很奇怪的异常。
异常详细信息: System.ArgumentOutOfRangeException: “DropDownList1”有一个无效 SelectedValue,因为它不在项目列表中。
于是查了一下MSDN:DropDownList.SelectedValue 属性:
此属性返回选定的 ListItem 的 Value 属性。通常使用 SelectedValue 属性确定列表控件中选定项的值。如果选定了多个项,则返回索引最小的选定项的值。如果未选定任何项,则返回一个空字符串 ("")。
SelectedValue 属性还可以用于选择列表控件中的某一项,方法是用该项的值设置此属性。如果列表控件中的任何项都不包含指定值,则会引发 System.ArgumentOutOfRangeException。
检查了一下代码。发现自己在没有绑DropDownList1之前就给DropDownList1.SelectedValue ="qqcrazyer";
怪不得出现异常;这里的DropDownList1没有qqcrazyer这一项。
但是这样赋值在做如市、县连动的值改时候很难避免不碰到赋一个列表没有的值,
怎么办呢?
于是又去反射查了一下SelectedValue的实现,找到了解法。原来只有在this.Page.IsPostBack的情况下,赋值才会出错。只需这样赋值:
DropDownList1.SelectedIndex = DropDownList1.Items.IndexOf(DropDownList1.Items.FindByValue("qqcrazyer"));
就是如果通过FindByValue没有找到指定项则为null,而Items.IndexOf(null)会返回-1.
还有一种方法就是改一下你的代码,改成
<asp:DropDownList ID="DropDownList1" runat="server" DataSourceID="SqlDataSource2"
DataTextField="a_code" DataValueField="a_code" SelectedValue='<%# Bind("a_code") %>' AppendDataBoundItems="True">
<asp:ListItem Value='' >(无)</asp:ListItem>
</asp:DropDownList>
在绑定的数据前加上一项(无),它对应null值。这样就不会出错了。
不过上述办法只是让它不出错而已,如果是因为页面加载时数据未绑定而导致上述错误,则最好是在页面加载时用一静态变量保存将要赋予下拉列表的值,等数据加载完毕,在下拉列表的DataBound(object sender, EventArgs e)事件中使用DropDownList1.SelectedIndex = DropDownList1.Items.IndexOf(DropDownList1.Items.FindByValue("qqcrazyer"));则能给综赋予想要给的值,前提是这个值本是它item值中之一,只是因为数据未绑定才导致上述错误的.
转摘自http://hi.baidu.com/nirvanan/blog/item/cce523964c09bb6a54fb96ac.html
c3836652-f2ef-4e10-ba32-5e84efc8255f|0|.0