一、
ADO 与ADO.NET两种数据访问方式区别?
1. ADO与ADO.NET简介
ADO与ADO.NET既有相似也有区别,他们都能够编写对数据库服务器中的数据进行访问和操作的应用程序,并且易于使用、高速度、低内存支出和占用磁盘
空间较少,支持用于建立基于客户端/服务器和 Web 的应用程序的主要功能。但是ADO使用OLE DB接口并基于微软的COM技术,而ADO.NET拥有自己的ADO.NET接口并且基于微软的.NET体系架构。众所周知.NET体系不同于COM体 系,ADO.NET接口也就完全不同于ADO和OLE DB接口,这也就是说ADO.NET和ADO是两种数据访问方式。
2. 数据访问方式的历史
下面简单的回顾一下微软的数据访问方式所走过的几个阶段。
ODBC – (Open Database Connectivity)是第一个使用SQL访问不同关系数据库的数据访问技术。使用ODBC应用程序能够通过单一的命令操纵不同的数据库,而开发人员需要做的仅仅只是针对不同的应用加入相应的ODBC驱动。
DAO - (Data Access Objects)不像ODBC那样是面向C/C++程序员的,它是微软提供给Visual Basic开发人员的一种简单的数据访问方法,用于操纵Access数据库。
RDO – 在使用DAO访问不同的关系型数据库的时候,Jet引擎不得不在DAO和ODBC之间进行命令的转化,导致了性能的下降,而RDO(Remote Data
Objects)的出现就顺理成章了。
OLE DB – 随着越来越多的数据以非关系型格式存储,需要一种新的架构来提供这种应用和数据源之间的无缝连接,基于COM(Component
Object Model)的OLE DB应运而生了。
ADO – 基于OLE DB之上的ADO更简单、更高级、更适合Visual Basic程序员,同时消除了OLE DB的多种弊端,取而代之是微软技术发展的趋势。
3. ADO与ADO.NET对照
在开始设计.NET体系架构时,微软就决定重新设计数据访问模型,以便能够完全的基于XML和离线计算模型。两者的区别主要有:
ADO以Recordset存储,而ADO.NET则以DataSet表示。Recordset看起来更像单表,如果让Recordset以多表的方式 表示就必须在SQL中进行多表连接。反之,DataSet可以是多个表的集合。ADO 的运作是一种在线方式,这意味着不论是浏览或更新数据都必须是实时的。ADO.NET则使用离线方式,在访问数据的时候ADO.NET会利用XML制作数
据的一份幅本,ADO.NET的数据库连接也只有在这段时间需要在线。
由于ADO使用COM技术,这就要求所使用的数据类型必须符合COM规范,而ADO.NET基于XML格式,数据类型更为丰富并且不需要再做COM编排导致的数据类型转换,从而提高了整体性能。
4. 小结
ADO.NET为.NET构架提供了优化的数据访问模型,和基于COM的ADO是完全两样的数据访问方式。
二、DataSet与DataReader的区别
ADO.NET 提供以下两个对象,用于检索关系数据并将其存储在内存中:DataSet和DataReader。DataSet提供一个内存中数据的关系表示形式,一整
套包括一些表在内的数据(这些表包含数据、对数据进行排序并约束数据),以及表之间的关系。DataReader提供一个来自数据库的快速、仅向前、只读
数据流。
当使用DataSet时,经常会利用DataAdapter(也可能是CommandBuilder)与数据源进行交互。当使用 DataSet时,也可以利用DataView对DataSet中的数据应用排序和筛选。也可以从DataSet继承,创建强类型DataSet,用于将 表、行和列作为强类型对象属性公开。
下列主题包括的信息涉及:使用DataSet或DataReader的最佳时机、如何优化访问它们所包含数据、以及如何优化使用DataAdapter(包括CommandBuilder)和DataView的技巧。
DataSet与DataReader
当设计应用程序时,要考虑应用程序所需功能的等级,以确定使用DataSet或者是DataReader。
要通过应用程序执行以下操作,就要使用DataSet:
r 在结果的多个离散表之间进行导航。
r 操作来自多个数据源(例如,来自多个数据库、一个XML文件和一个电子表格的混合数据)的数据。
r 在各层之间交换数据或使用XML
Web服务。与DataReader不同的是,DataSet能传递给远程客户端。
r 重用同样的记录集合,以便通过缓存获得性能改善(例如排序、搜索或筛选数据)。
r 每条记录都需要执行大量处理。对使用DataReader返回的每一行进行扩展处理会延长服务于DataReader的连接的必要时间,这影响了性能。
r 使用XML操作对数据进行操作,例如可扩展样式表语言转换(XSLT转换)或XPath查询。
对于下列情况,要在应用程序中使用DataReader:
r 不需要缓存数据。
r 要处理的结果集太大,内存中放不下。
r 一旦需要以仅向前、只读方式快速访问数据。
注 填充DataSet时,DataAdapter使用DataReader。因此,使用DataAdapter取代DataSet提升的性能表现为节省了 DataSet占用内存和填充DataSet需要的循环。一般来说,此性能提升只是象征性的,因此,设计决策应以所需功能为基础。
三、基本概念
1、面向对象的语言具有封装性、继承性、多态性。
2、ADO.NET中的五个主要对象Connection、Command、DataSet、DataReader、DataAdapter
3、ASP.NET中的身份验证有Windows、Forms、Passport,一般采用Forms,比较简单、适用面广
4、接口-- --接口定义了一组方法(Method,子程序或函数例程[译注:指Visual Basic .NET中的Sub和Function])、属性(Property)、事件(Event)和域(Field,变量或特性),这些都被声明为公有。接口也 可以被另一个接口继承。任何继承了一个接口的类或结构都必须实现接口继承链中所有接口所定义的成员。
5、继承------继承是指一个类——称为子类[译注:亦称派生类],可以基于另一个类——称为基类[译注:亦称父类、超类]。继承提供了一种建立对象层次的机制。继承使得你能够在你自己的类中使用另外一个类的接口和代码。
base->访问基类的成员。
this->引用调用一个方法的当前对象。
6、抽象类-------抽象类是一种特殊的基类。除了通常的类成员,它们还带有抽象类成员。抽象类成员是指没有实现而只有声明的方法和属性。所有直接从抽象类派生的类都必须实现所有这些抽象方法和属性。
抽 象方法不能实例化。这样做[译注:指实例化一个抽象类]是不合逻辑的,因为那些抽象成员没有实现。那么,不能实例化一个类有什么好处呢?很多!抽象类稳坐 类继承树的顶端。它们确定了类的结构和代码的意图。用它们可以得到更易搭建的框架。这是可能的,因为抽象类具有这个框架中所有基类的一般信息和行为。
7、接口和抽象类之间的区别--------接口和抽象类关系很紧密,它们都具有对成员的抽象。
对于一个抽象类,至少一个方法是抽象方法既可,这意味着它也可以具有具体方法[译注:Concrete
Method,这只是相对于抽象方法而言,面向对象中并没有这个概念]。
对于一个接口,所有的方法必须都是抽象的。
实现了一个接口的类必须为接口中的所有方法提供具体的实现,否则只能声明为抽象类。
在C#中,多重继承(Multiple Inheritance)只能通过实现多个接口得到。抽象类只能单继承[译注:C#中的单继承是指所有类作为基类的时候都只能是派生类声明中唯一的基类,而不仅仅是抽象类]。
接口定义的是一个契约,其中只能包含四种实体,即方法、属性、事件和索引器。因此接口不能包含常数(Constant)、域、操作符、构造器、析构器、静态构造器或类型[译注:指嵌套的类型]。
同时,一个接口还不能包含任何类型的静态成员。修饰符abstract、public、protected、internal、private、virtual、override都是不允许出现的,因为它们在这种环境中是没有意义的。
类中实现的接口成员必须具有公有的可访问性。
· C#中的接口是独立于类来定义的。这与 C++模型是对立的,在 C++中接口实际上就是抽象基类。
· 接口和类都可以继承多个接口。
· 而类可以继承一个基类,接口根本不能继承类。这种模型避免了 C++的多继承问题,C++中不同基类中的实现可能出现冲突。因此也不再需要诸如虚拟继承和显式作用域这类复杂机制。C#的简化接口模型有助于加快应用程序的开发。
· 一个接口定义一个只有抽象成员的引用类型。C#中一个接口实际所做的,仅仅只存在着方法标志,但根本就没有执行代码。这就暗示了不能实例化一个接口,只能实例化一个派生自该接口的对象。
· 接口可以定义方法、属性和索引。所以,对比一个类,接口的特殊性是:当定义一个类时,可以派生自多重接口,而你只能可以从仅有的一个类派生。
8、多态性-- ------多态性反映了能够在多于一个类的对象中完成同一事物的能力——用同一种方法在不同的类中处理不同的对象。例如,如果Customer和 Vendor对象都有一个Name属性,则我们可以写一个事物来调用Name属性而不管我们所使用的是Customer对象还是Vendor对象,这就是 多态性。
交通工具是多态性的一个很好的例子。一个交通工具接口可以只包括所有交通工具都具有的属性和方法,还可能包括颜色、车门数、变速器和点火
器等。这些属性可以用于所有类型的交通工具,包括轿车、卡车和挂车。 多态性不在交通工具的属性和方法背后实现代码。相反,多态性只是实现接口。如果轿车、卡车和挂车都实现了同样的交通工具接口,则所有这三个类的客户代码是
完全一样的。
C#通过继承来为我们提供多态性。C#提供了virtual关键字用于定义一个支持多态的方法。
9、结构----------结构是和类相似的一种封装构造,因为它可以包含数据、类型和函数成员。但和类不同的
是,结构是值类型,因此存放在内存中称为栈的地方。结构通常用来存入简单数据类型--
在内存中有固定大小的实体----的集合,事实上,内建的基本值类型Int32、Int64、Double
等在.NET
Framework中实现为结构。
10、委托-- -------委托是提供对具有特定返回类型和参数列表的方法的一般引用的引用类型。它的本质上和C或C++中的函数指针相似。但和C++函数指针不同的 是,委托是完全面向对象的---它们既封装方法又封装对象实例。委托是用户定义的类型,所以当定义委托时,实际上是定义一个特定类型的委托,而不是一个具
体的实例
11、.Net中的内存回收机制
垃圾回收器是用来管理应用程序的内存分配和释放 的。在垃圾回收器出现以前,程序员在使用内存时需要向系统申请内存空间。有些语言,例如Visual Basic,可以自动完成向系统申请内存空间的工作。但是在诸如Visual C++的语言中要求程序员在程序代码中申请内存空间。如果程序员在使用了内存之后忘了释放内存,则会引起内存泄漏。但是有了垃圾回收器,程序员就不必关心
内存中对象在离开生存期后是否被释放的问题。当一个应用程序在运行的时候,垃圾回收器设置了一个托管堆。托管堆和C语言中的堆向类似,但是程序员不需要从 托管堆中释放对象,并且在托管堆中对象的存放是连续的。
每次当开发人员使用
new 运算符创建对象时,运行库都从托管堆为该对象分配内存。新创建的对象被放在上次创建的对象之后。垃圾回收器保存了一个指针,该指针总是指向托管堆中最后一
个对象之后的内存空间。当新的对象被产生时,运行库就知道应该将新的对象放在内存的什么地方。同时开发人员应该将相同类型的对象放在一起。例如当开发人员
希望向数据库写入数据的时侯,首先需要创建一个连接对象,然后是Command对象,最后是DataSet对象。如果这些对象放在托管堆相邻的区域内,存 取它们就非常快。
12、.反射和序列化
反射:程序集包含模块,而模块包含类型,类型又包含成员。反射则提供了封装程序集、模块和类型的对象。您可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。然后,可以调用类型的方法或访问其字段和属性
序列化:序列化是将对象转换为容易传输的格式的过程。例如,可以序列化一个对象,然后使用 HTTP 通过 Internet 在客户端和服务器之间传输该对象。在另一端,反序列化将从该流重新构造对象。
13、.关于值类型和引用类型
数据在内存中的存储位置,取决于它的数据类型,在C#中,分为值类型和引用类型,值类型的数据存储在内存中的堆栈中,每个变量或程序都有自己的堆栈,不可以共用一个堆栈地址。当数据一个值类型的变量传递到另一个相同类型的变量时,会在堆栈中分配两个不同的地址。
而引用类型的数据存储在内存中的堆中,可以不同的变量或程序共同使用同一个位置的数据。当数据从一个引用类型的变量传递到另一个相同类型的变量时,只是把这个变量的引用地址传递给新的变量,同时引用当前堆中存储的数据。
四、Public、Protected、Internal、Protected internal、Private的访问权限
1、Public ------公共成员,成员对于任何人都是可见的。我们可以在类内部的和类的子孙的代码中通过使用类的实例来访问一个公有的成员。
2、Protected------保护成员,成员和私有成员类似,只能由包含它的类访问。然而,受保护成员可以由一个类的子类所使用。如果类中的一个成员可能被该类的子类访问,它应该声明未受保护的
3、
Internal/Friend--------成员对整个应用程序是公有的,但对于其他的外部应用程序是私有的。当我们希望其他应用程序能够使用当前应
用程序中的包含的一个类,但又希望这个类为当前应用程序保留一定的功能时,就要用到内部/友元成员。在C#中我们使用internal,而在Visual Basic .NET中我们使用Friend。
4、Protected
internal -------包括了Protected和Internal修饰符,成员只能由包含了基类的应用程序中的从该基类派生的子类所访问。当你希望一个类中的成
员只能由其子类访问,并且拒绝其他应用程序访问该类的这个成员的时候,你就要将其声明未受保护内部成员。
5、Private
-------私有成员,成员是隐藏的,只有对类本身是可用的。所有使用了一个类的实例的代码都不能直接访问一个私有成员,这个类的子类也不允许。