[ASP.NET学习笔记之六]开发高性能的ADO.NET应用
来源:互联网 发布:mysql更新语句怎么写 编辑:程序博客网 时间:2024/04/30 12:02
开发高性能的ADO.NET应用
ADO.NET概述
面向连接模型
l ADO.net 1.x读取数据时必须保存稳定的连接而且在每个连接上只能使用一个DataReader。
l ADO.net 2.0无此限制!一个连接可以打开多个DataReader
ADO.NET性能最佳实践
选用合适的Data Provider
l SQL Server .NET Data Provider
SQL Server 7.0 或2000
通过TDS访问数据库
l OLE DB .NET Data Provider
SQL Server 6.5, Microsoft Access, Oracle, 或其他具有
OLE DB 提供者的数据库。
l ODBC .NET Data Provider
某些旧的系统
l .NET Data Provider for Oracle
Oracle
l Custom .NET Data Provider
[注意] 可以自定义Data Provider,这个接口在.NET是公开的,你能够自己实现这些类。
下面的图示数据库连接的比较:
Provider Factories
l 在应用开发时,我们很多时候并不清楚目标环境是什么数据库,特别是做产品的时候。
l ADO.NET 1.x使用接口(IConnection IDataAdapter等等)来实现在数据库的无关性,但程序员还是要写很多代码。
l ADO.NET 2.0使用了一些数据库无关的抽象类与接口,并提供“DbProviderFactory” 来获得相应数据提供者。
真正的DataProvider。这是一个实现层,完成了数据库具体提供者。
DbProviderFactory Methods
CreateConnection
CreateCommand
CreateCommandBuilder
CreateConnection
CreateConnectionStringBuilder
CreateDataAdapter
CreateDataSourceEnumerator
CreateParameter
CreatePermission
相关资料可以查阅MSDN。我们可以通过它们创建访问数据库需要的连接指令 Adapter 参数 权限 数据源等等
DbProviderFactories methods
DbProviderFactories Method
Purpose
GetFactoryClasses()
Returns a DataTable of provider information from the information in machine.config
GetFactory(DataRow)
Returns the correct DbProviderFactory instance given a DataRow from the DataTable produced by GetFactoryClasses
GetFactory(string)
Returns the correct DbProviderFactory instance given a provider-invariant name string that identifies the provider
GetFactory(string):这里面string 你把可以把它写到配置文件(machine.config)
注册数据提供者
ADO.NET 2.0 可以在machine.config来注册数据提供者,在程序中可以按名字找到相应
数据提供者。通过下面的注册,当我要用SqlClient Data Provider,就只知道是用这个类来实现的
<system.data>
<DbProviderFactories>
<add name="SqlClient Data Provider" invariant="System.Data.SqlClient" support="FF" description=".Net Framework Data Provider for SqlServer"
type="System.Data.SqlClient.SqlClientFactory, System.Data,Version=2.0.3600.0, Culture=neutral,PublicKeyToken=b
<!-- other provider entries elided -->
</DbProviderFactories>
</system.data>
Factory例子(base)
enum provider {sqlserver, oracle, oledb, odbc};
public DbConnection GetConnectionBaseClass()
{
// determine provider from configuration
provider prov = GetProviderFromConfigFile();
DbConnection conn = null;
switch (prov)
{
case provider.sqlserver:
conn = new SqlConnection();
break;
case provider.oracle:
conn = new OracleConnection();
break;
// add new providers as the application supports them
}
return conn;
}
为什么能够这样实现呢?这是因为ADO.NET2.0中的DBConenection抽象类,而在ADO.NET1.1中只有IConnenction这个接口
Factory例子(Adv)
// get ProviderInvariantString from configuration
string provstring = GetProviderInvariantString();
DbProviderFactory fact = DbProviderFactories.GetFactory(provstring);
IDbConnection = fact.CreateConnection();
以上两种方式都能够实现DataProvider
数据库连接
连接
l 在方法中打开和关闭连接明确地关闭连接。
l 当使用DataReaders, 指定CommandBehavior.CloseConnection 。
l 当使用Fill或Update方法时,不要手工打开连接。
l 避免检查OleDbConnection 的State属性,带来额外的消耗。
l 使用连接池
连接池
在默认情况下,连接池自动打开。可以通过连接字符串的参数控制连接池:
Max Pool Size (default = 100)
Min Pool Size (default = 0)
Pooling (default = true)
Conn.ConnectionString="Server=localhost; Integrated Security=SSPI; Database=Northwind;Max Pool Size=75; Min Pool Size=5;Pooling=true;";
打开和关闭连接
l DataAdapter能根据需要自动打开和关闭连接。
l 使用Command对象时,则需要手动打开和关闭连接
SQL指令
l 校验SQL的输入并使用参数
l 仅返回需要的行和例
l 对大的数据集使用分页功能
l 批次执行SQL ,减少往返
l 如果没有数据返回则使用ExecuteNonQuery方法
l 当返回一个标量时,使用ExecuteScalar方法
l 不要在运行时间使用CommandBuilder
批次执行SQL
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "ReadCustomerAndOrders";
// The stored procedure returns multiple result sets.
SqlDataReader myReader = cmd.ExecuteReader();
if (myReader.read())
//... read first result set
reader.NextResult();
if (myReader.read())
//... read
存储过程
l 尽量使用存储过程
一般SQL语句需要执行五步:解释 解析 优化 编译 执行,所以存储过程只需要执行最后一步
l 对于OleDbCommand,指令类型为CommandType.Text
l 使用SqlCommand时,指令类型为CommandType.StoredProcedure
l 考虑使用Command.Prepare(),这是因为在后台做一个编译存储起来
l 尽可能使用输出参数
l 考虑在SQL Server上SET NOCOUNT ON。我们可以从查询分析器中可以看见没做一次执行,都会给一个统计反映多少行修改,我们可以把它关闭,使SQL语句执行更快。
参数
l 在存储过程上使用参数
SqlDataAdapter myCommand = new SqlDataAdapter("AuthorLogin", conn);
myCommand.SelectCommand.CommandTyp
e = CommandType.StoredProcedure;
SqlParameter parm=myCommand.SelectCommand.Parameters.Add("@au_id", SqlDbType.VarChar, 11);
parm.Value = Login.Text;
l 使用参数化SQL语句
SqlDataAdapter myCommand = new SqlDataAdapter SqlDataAdapter("SELECT au_lname, au_fname FROM Authors WHERE au_id = @au_id", conn);
SqlParameter parm = myCommand.SelectCommand.Parameters.Add("@au_id",SqlDbType.VarChar, 11);
parm.Value = Login.Text;
l 创建参数并指定类型
l 可将参数对象进行缓存
事务
l 使用数据库事务(存储过程)
BEGIN TRAN
UPDATE Orders SET Freight=@Freight Where OrderID=@OrderID
UPDATE [Order Details] SET Quantity=@Quantity Where OrderID=@OrderID
IF (@@ERROR > 0)
ROLLBACK TRANSACTION
ELSE
COMMIT TRANSACTION
[注意] 如果你的事务判断条件都在数据库里面,就考虑使用数据库事务,它的效率最高
l 使用ADO.NET的事务(编程)
SqlConnection conn = new SqlConnection(connString);
SqlTransaction trans = conn.BeginTransaction();
try
{
SqlCommand cmd = new SqlCommand("MyWriteProc",conn, trans);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(.......);
// additional transactioned writes to database
trans.Commit();
}
catch
{
trans.Rollback();
}
l 使用分布式事务,由多个数据库的更新,考虑分布式事务,虽然效率很差。
l 尽可能使用短事务,这是因为资源锁定的时间比较长。
l 使用适当的事务隔离级别,避免并发行很差。
l 避免死锁
- [ASP.NET学习笔记之六]开发高性能的ADO.NET应用
- [ASP.NET学习笔记之三十三]开发高性能的Web Service应用
- 开发高性能的 ASP.NET 应用程序
- 开发高性能的ASP.NET 应用程序
- 开发高性能的 ASP.NET 应用程序
- ASP.NET学习笔记之ADO.NET(一)
- ASP.NET学习笔记之ADO.NET(一)
- [ASP.NET学习笔记之三]ADO.NET开发最佳实践
- ADO.NET学习笔记(六)
- ADO.NET的数据提供程序和数据连接——ADO.NET学习&应用笔记之二
- ADO.NET的数据提供程序和数据连接——ADO.NET学习&应用笔记之二
- 黑马程序员之ASP.NET学习笔记: 几个常用方法有效优化ASP.NET的性能
- asp.net在高性能应用的最佳实践
- 构建高性能的ASP.NET应用(五)
- 构建高性能ASP.NET应用的几点建议
- 构建高性能 ASP.NET应用的12点建
- 构建高性能的ASP.NET应用(8)
- 构建高性能的ASP.NET应用(8)
- TEST
- Design Patterns -- Factory Method
- 一个较简易的分页javascript类
- Lotus Sametime 开发入门: 使用客户端 ToolKit 与 Sametime 服务器交互
- Biztalk 实例之 从SQL Server中获取数据
- [ASP.NET学习笔记之六]开发高性能的ADO.NET应用
- 经典收藏 C++内存管理操作详解
- 程序人生 - 开发工程师人生之路
- ClearCase Deliver过程解析
- 贝多芬的弦乐四重奏
- TEST3
- 刘翔12秒88破世界纪录...
- smart1.0稳定版 终于在sourceforge released
- 资料碟太多了