ADO.NET架构

本文涉及的产品
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
云数据库 RDS SQL Server,基础系列 2核4GB
简介: 2010年7月18日记 ADO.NET架构 1、使用ADO.NET连接最佳练习 2、使用ADO.NET命令最佳练习 3、使用DataReader、DataSet、DataAdapter 4、使用ADO.

2010718

ADO.NET架构

1、使用ADO.NET连接最佳练习

2、使用ADO.NET命令最佳练习

3、使用DataReaderDataSetDataAdapter

4、使用ADO.NET的其他技巧

 

ADO.NET架构

1Data Provider

SQL Server Provider

SqlConnection/SqlCommand/SqlDataAdapter/SqlDataReader

OleDbProvider

OleDbConnection/OleDbCommand/OleDbDataAdapter/OleDbDataReader

2DataSet

DataTable

DataColumn

DataRow

Constraints

DataRelation

3Data use application

Windows Form

Web Form

Others

 

1、数据提供程序:

SQL Server .NET数据提供程序

OLE DB.NET数据提供程序

ODBC .NET数据提供程序

基于Oracle.NET数据提供程序

2、对象概述

Connection类:在代码和容纳数据的数据存储之间提供了基本的连接

Command类:用于描述SQL语句或者通过其Connection类执行的存储过程

DataReader类:从数据源中获取只读的数据流

DataAdapter类:功能最强大、更复杂的对象,可以读取、改变数据源

 

ADO.NET连接最佳练习

1、使用连接池

DataAdapter优化连接

始终关闭ConnectionDataReader

C#中使用“Using”语句

异常处理

安全连接

2、为什么使用连接池?

创建连接所发费的时间与资源并不是无价值的

Connection pools可以使在特定页面运行过后,连接能够保持下来

3、使用连接池和不使用连接池的对比

1、使用连接池:在连接池中,判断是否已有连接?

没有连接,那么创建数据连接,然后向数据库发送查询请求,将返回的数据显示,最后断开连接

如果连接池中已有连接,那么直接向数据库发送查询请求,将返回的数据显示,最后断开连接

2、不使用连接池:直接创建数据连接,然后向数据库发送查询请求,将返回的数据显示,最后断开连接

显然,连接池减少了数据连接上的性能消耗,效率肯定比不使用连接池高

 

4ADO.NET中的连接池

如果使用的是OleDbConnection类,则连接池将由提供程序自动处理,而不必自己进行管理。

如果使用的是SqlConnection类,则连接池被隐式管理,但也提供选项允许自己管理连接池。

在连接池字符串中指定:

Pooling=true;//默认为true

Connection lifetime=5; //默认为0

Min pool size=1; //默认为0

Max pool size=50; //默认为100

 

DataAdapter优化连接

1DataAdapterFillUpadate方法在连接关闭的情况下自动打开为相关命令属性指定的连接。如果Fill或者Update方法打开了连接,Fill或者Update将在操作完成的时候关闭它。为了获得最佳性能,仅在需要时将与数据库的连接保持为打开,同时,减少打开和关闭多操作连接的次数。

2、如果只执行单个的FillUpdate方法调用,建议允许FillUpdate方法隐式打开和关闭连接。如果对Fill/Update调用很多,建议显示打开连接,调用Fill/Update,然后显示关闭连接。

3、始终关闭ConnectionDataReader

完成对ConnectionDataReader对象的使用后,总是显示地关闭它们。尽管垃圾回收最终会清除对象并释放连接和其他委托资源,但垃圾回收仅在需要时执行。

4、在C#中是偶那个“Using”语句

Using语句在离开自己的作用范围时,会自动调用被“使用”的对象的Dispose

 

连接异常

1DataException类:表示使用ADO.NET组件发生错误时引发的异常

2DBConcurrencyException类:在更新操作过程中受影响的行数等于0时,由DataAdapter所引发的异常。

3SqlException类:当SQL Server返回警告或错误时引发的异常。无法继承此类。

属性

任何时候只要SQL Server.NET数据提供程序遇到服务器生成的错误,就会创建该类。SqlException始终包含至少一个SqlError实例。

1、严重程度等于或者小于10的消息是信息性消息,它们指示由用户输入信息中的错误所导致的问题。严重程度1116的消息是由用户生成的,可以由用户更正。严重程度171819的错误时,虽然可能无法执行特定语句,但仍可以继续工作。

2、当严重程度等于或者小于19时,SqlConnection保持打开状态。当严重程度等于或大于20时,服务器通常会关闭SqlConnection。但是,用户可以重新打开连接并继续操作。在这两种情况下,执行命令的方法都会生成SqlException

Private void btnTest_Click(object sender,System.EventArgs e)

{

string strConUnusePool=”Server=localhost;Integrated Security-SSPI;database=mydatabase;pooling=false”;

string strConusePool=”Server=localhost;Integrated Security=SSPI;database=mydatabase;”

+”pooling=true;connction lifetime=5;”;

Int nConNum=50;

//计算不使用连接池创建连接的时间

DateTime dtStart=DateTime.Now;

for(int i=1;i<=nConNum;i++)

{

Using(SqlConnection con=new SqlConnection(strConUnusePool))

{con.Open();con.Close();}

}

DateTime dtEnd=DateTime.Now;

TimeSpan ts=dtEnd-dtStart;

lbUnUse.Text=ts.Milliseconds.ToString();

//计算使用连接池的时间

dtStart=DateTime.Now;

for(int i=1;i<=nConNum;i++)

{

Using(SqlConnection con=new SqlConnection(strConusePool))

{con.Open();con.Close();}

}

dtEnd=DateTime.Now;

ts=dtEnd-dtStart;

lbUse.Text=ts.Milliseconds.ToString();

}

Private void btnScurity_Click(object sender,System.EventArgs e)

{

String strCon=”server=(local);database=mydatabase;uid=sa;pwd=111;pooling=false;”;

SqlConnection con=new SqlConnection(strCon);

String strSql=”select * from ScoreTable where UserName=’”+tbUserName.Text.Replace(“’”,”””);

SqlCommand com=new SqlCommand(strSql,con);

con.Open();

SqlDataReader sdr=com.ExecuteReader();

if(sdr.Read())

MessagerBox.Show(“Authenticated”);

else

MessageBox.Show(“Invalid User”);

sdr.Close();

con.Close();

}

使用命令最佳练习

1Command对象的使用

使用SqlCommand的最佳练习

使用Prepare方法

显示指定架构和元数据

测试Null

Null作为参数值传递

执行事务

Command对象的使用

2、方法和描述

Cancel:取消数据命令的执行

CreateParameter:创建一个新的参数

ExecuteNonQuery:执行命令并返回受影响的行数

ExecuteReader;执行命令并返回生成的DataReader

ExecuteScalar:执行查询并返回结果集中的第一行的第一列

ExecuteXmlReader:执行命令并返回生成的XMLReader

Prepare:在数据源上创建一个准备好的命令版本

ResetCommandTimeOut:将CommandTimeOut属性重置为默认值

3DataReader

当数据命令返回结果集时,用DataReader来检索数据

DataReader对象返回一个来自数据命令的只读的、只能向前的数据流

内存中每次仅有一行数据行,因此开销很少。

4ExecuteScalarExecuteNonQuery

如果想返回像Count*)、SumPrice)或AvgQuantity)的结果那样的单值,可以使用Command.ExecuteScalar

因为单独一步就能完成,所以ExecuteScalar不仅简化了代码,还提高了性能;要是使用DataReader就需要两步才能完成(即,ExecuteReader+取值)。

使用不返回行的SQL语句时,例如修改数据(例如INSERTUPDATEDELETE)或仅返回输出参数或返回值,请使用ExecuteNonQuery。这避免了用于创建空DataReader的任何不必要处理。

5、使用SqlCommand的最佳练习

存储过程是SQLServer数据库的一个重要特色

存储过程执行效率比SQL文本命令要高得多

提高了程序的复杂性

存储过程中可以使用变量和条件

可以在存储过程中使用参数

如果调用存储过程,将SqlCommandCommandType属性指定为StoredProcedureCommandType。这样通过将该命令显示标识为存储过程,就不需要在执行之前分析命令。

使用Prepare方法

对于重复作用与数据源的参数化命令,Command.Prepare方法能提高性能。

对于一些数据源(例如SQL Server 2000),命令是隐式优化的,不必调用Prepare

对于其他(例如SQLServer7.0)数据源,Prepare会比较有效。

1、测试Null

如果表(在数据库中)中的列允许为空,就不能测试参数值是否“等于”空

Select * from Customers where ((LastName=@LastName) or (LastName is null and @LastName is null))

2、把Null作为参数值传递;

对数据库的命令中,当把空值作为参数值发送时,不能使用nullVisual Basic.NET中的Nothing)。而需要使用DBNull.Value

事务处理

 

ADO.NET的事务模型已经更改

1、在AOD中,当调用StartTransaction时,调用之后的任何更新操作都被视为是事物的一部分。但是,在ADO.NET中,当调用Connection.BeginTransaction时,会返回一个Transaction对象,需要把它与CommandTransaction属性联系起来。这种设计可以在一个单一连接上执行多个根事务。

2、如果未将Command.Transaction属性设置为一个针对相关的Connection而启动的Transaction,那么Command就会失败并引发异常。

Class TransDemo

{

Public void DoDemo()

{

SqlConnection con=new SqlConnection(“Server=localhost;Integrated Security=SSPI;database=mydatabase;”);

SqlCommand cmdUpdateScore=new SqlCommand(“UpdateScore”,con);

cmdUpdateScore.CommandType=CommandType.StoredProceduce;

cmdUpdateSocre.Parameters.Add(new SqlParameter(“@username”,”周润发”));

cmdUpdateScore.Parameters.Add(new SqlParameter(“@score”,”700”));

con.Open();

SqlTransaction trans=con.BeginTransaction();

cmdUpdatScore.Transaction=trans;

try

{

cmdUpdateScore.ExecuteNonQuery();

trans.Commit();//no error so commit the transaction

}

catch

{

Trans.Rollback();//rollback the update

}

}

}

议程

1ADO.NET架构

2、使用ADO.NET连接最佳练习

3、使用ADO.NET命令最佳练习

4、使用DataReaderDataSetDataAdapter

5、使用ADO.NET的其他技巧

 

使用DataReaderDataSetDataAdapter

DataSet是一种代表关系数据的内存驻留结构

DataTableCollection

DataTable

Columns

DataColumn

Rows

DataRow

Constraints

Constraint

 

DataRelationCollection

DataRelation

 

ADO.NET

DataProvider

Connection<->DataAdapter对象   <-> DataSet <-> Data Use Application

         <->Command对象                   Windows Forms

           DataReader对象                   Web Forms

                                            Others

1、执行以下操作使用DataSet

在结果的多个离散表之间进行导航。

操作来自多个数据源(例如,来自多个数据库、一个XML文件和一个电子表格的混合数据)的数据

在各层之间交换数据或使用XML Web服务。

重用同样的行组,以便通过缓存获得性能改善(例如排序、搜索或筛选数据)。

每行执行大量处理。

 

2、对于下列情况,要在应用程序中使用DataReader

不需要缓存数据。

要处理的结果集太大,内存中放不下。

一旦需要以只进、只读方式快速访问数据。

 

3DataReader的常见问题:

在访问相关Command的任何输出参数之前,必须关闭DataReader。完成读数据之后总是要关闭DataReader

当访问列数据时,使用类型化访问器

一个单一连接每次只能打开一个DataReader

默认情况下,DataReader每次Read时都要把整行加载到内存。这允许在当前行内随即访问列。如果不需要这种随即访问,为了提高性能,就把CommandBehavior.SequentialAccess传递给ExecuteReader调用

如果已经完成读取来自DataReader的数据,但仍然有大量挂起的未读结果,就在调用DataReader的数据,但仍然有大量挂起的未读结果,就在调用DataReader的数据,但仍然有大量挂起的未读结果,就在调用DataReaderClose之前先调用CommandCancel

4、二进制大对象(BLOB

DataReader检索二进制大对象(BLOB)时,应该吧CommandBehavior.SequentialAccess传递给ExecuteReader方法调用。

SequentialAccessDataReader的行为设置为只加载请求的数据。然后还可以使用GetBytesGetChars控制每次加载多少数据。

Public void ExecuteNonQuery()

{

SqlConnection con=new SqlConnection(“Server=localhost;Integrated Security=SSPI;database-mydatabase;”);

SqlCommand cmdUpdateSales=new SqlCommand(“Update scoretable set score=score+200 where username=’who’”,con);

cmdUpdateSales.CommandType=CommandType.Text;

con.Open();

cmdUpdateSales.ExecuteNonQuery();

con.Close();

}

Public DataSet ExecuteAndFill()

{

SqlConnection con=new SqlConnection(“Server=localhost;Integrated Security=SSPI;database=mydatabase;”);

SqlDataAdapter da=new SqlDataAdapter(“select username,password,score from scoretable”,con);

DataSet ds=new DataSet();

con.Open();

da.Fill(ds);

return ds;

}

 

其他技巧

1、避免自动增量值冲突

2、检查开放式并发冲突

3、多线程编程

4、仅在需要的时候才用COM Interop访问ADO

 

小结

1ADO.NET架构

2、连接练习

3、命令练习

4、使用DataReaderDataSetDataAdapter

相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS&nbsp;SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/sqlserver
目录
相关文章
|
6月前
|
存储 开发框架 前端开发
前端框架EXT.NET Dotnet 3.5开发的实验室信息管理系统(LIMS)成品源码 B/S架构
发展历史:实验室信息管理系统(LIMS),就是指通过计算机网络技术对实验的各种信息进行管理的计算机软、硬件系统。也就是将计算机网络技术与现代的管理思想有机结合,利用数据处理技术、海量数据存储技术、宽带传输网络技术、自动化仪器分析技术,来对实验室的信息管理和质量控制等进行全方位管理的计算机软、硬件系统,以满足实验室管理上的各种目标(计划、控制、执行)。
68 1
|
1月前
|
存储 消息中间件 前端开发
.NET常见的几种项目架构模式,你知道几种?
.NET常见的几种项目架构模式,你知道几种?
|
3月前
|
设计模式 存储 前端开发
揭秘.NET架构设计模式:如何构建坚不可摧的系统?掌握这些,让你的项目无懈可击!
【8月更文挑战第28天】在软件开发中,设计模式是解决常见问题的经典方案,助力构建可维护、可扩展的系统。本文探讨了.NET中三种关键架构设计模式:MVC、依赖注入与仓储模式,并提供了示例代码。MVC通过模型、视图和控制器分离关注点;依赖注入则通过外部管理组件依赖提升复用性和可测性;仓储模式则统一数据访问接口,分离数据逻辑与业务逻辑。掌握这些模式有助于开发者优化系统架构,提升软件质量。
58 5
|
3月前
|
XML 开发框架 .NET
.NET框架:软件开发领域的瑞士军刀,如何让初学者变身代码艺术家——从基础架构到独特优势,一篇不可错过的深度解读。
【8月更文挑战第28天】.NET框架是由微软推出的统一开发平台,支持多种编程语言,简化应用程序的开发与部署。其核心组件包括公共语言运行库(CLR)和类库(FCL)。CLR负责内存管理、线程管理和异常处理等任务,确保代码稳定运行;FCL则提供了丰富的类和接口,涵盖网络、数据访问、安全性等多个领域,提高开发效率。此外,.NET框架还支持跨语言互操作,允许开发者使用C#、VB.NET等语言编写代码并无缝集成。这一框架凭借其强大的功能和广泛的社区支持,已成为软件开发领域的重要工具,适合初学者深入学习以奠定职业生涯基础。
105 1
|
6月前
|
数据安全/隐私保护 Windows
.net三层架构开发步骤
.net三层架构开发步骤
|
开发框架 .NET 容器
.NET Core-依赖注入:良好架构的起点
.NET Core-依赖注入:良好架构的起点
|
开发框架 .NET 容器
.net core依赖注入:良好架构的起点
.NET Core使用依赖注入框架来管理服务的依赖与生命周期。
|
计算机视觉
Half-UNet:用于医学图像分割的简化U-Net架构
Half-UNet简化了编码器和解码器,还使用了Ghost模块(GhostNet)。并重新设计的体系结构,把通道数进行统一。
243 0
|
分布式计算 NoSQL Java
1..Net平台历程介绍和.net framework和netcore的架构体系对比,以及框架的选择介绍
1..Net平台历程介绍和.net framework和netcore的架构体系对比,以及框架的选择介绍
213 0
|
缓存 前端开发 JavaScript
采用.Net Core技术框架开发的医院云LIS平台源码,B/S架构
基于B/S架构的医学实验室检验系统源码,整个系统的运行基于WEB层面,只需要在对应的工作台安装一个浏览器软件有外网即可访问。全套系统采用云部署模式,部署一套可支持多家医院检验科共同使用。 采用.Net Core新的技术框架、DEV报表、前端js封装、分布式文件存储、分布式缓存等,支持LIS独立部署,Docker部署等多种方式。
147 0
下一篇
无影云桌面