ado.net的基本特性
Ado.net 在一些特性上与他的前一个数据连接技术有点不同,不同地方如下:
1、 Dataset
许多ado.net的工作都是围绕一个对象dataset来展开工作的,dataset是从数据库查询得来的缓存信息。dataset最革命性的特点是它是无连接的并且同时可以存储多个表并且可以定义他们之间的关系。
2、 无连接特性
无连接特性是ado.net最重要的特点,在先前的连接都是在代码工作的时候保持数据库连接,可以保持即时的更新但是它限制了连接的数目。无连接就不会出现这样的问题。
但是无连接也会带一些新的问题,它很容易造成不一致的更新。但是ado.net提供了一套特性来解决这些问题。
3、 XML集成
Ado.net很好的支持XML,当你用dataset对象时这个事实可能不是很明显,那是因为dataset的内置方法和属性可以很好的完成你需要管理的数据。但是如果你深入研究,你将会发现你接触dataset中的信息是作为一个xml文档。你甚至可以通过修改XML来修改值和删除行和增加记录,这个dataset会立马更新。
Ado.net 的功能主要依赖于一小部分核心对象的集合。可以将这些对象分成两部分:
1、容纳和管理数据的对象(比如dataset,datatable,datarow,datareleation)
2、用来连接某些数据源(比如 connection,command,datareader
数据容器对象是完全通用的,无论你使用什么数据源,一旦你提取了数据,都是用同一个dataset类来存储。
第二组对象存在很多不同的形式。数据连接对象的每一个集合都被称为ado.net data provider. Data providers都是自定义的,所以每一个都用自己最好的表现方式来连接它形相应的数据源。比如说SQL Server data provider是为SQL SERVER 7或以后版本而设计的。在内部,它用SQL Server’sTDS(tabular data stream)协议来进行通信,这样就能保证他最好的表现形式。
Data Namespace
ADO.NET 组件存在.net 类库的以下7个名空间中。这些名空间可以容纳ado.net的所有功能特性。这些命名空间如下:
1、 System.data
2、 System.data.common
3、 System.data.sqltypes
4、 System.data.sqlclient
5、 System.data.oledb
6、 System.data.odbc
7、 System.data.oracleclient
下面是一个连接sql数据库简单的例子,是直接通过提供了sql数据源连接字符串。
myConnncetion.ConnectionString=”Data source=localhost\\sqlexpress; initial catalog=pubs; integrated security=sspi”;
这里有一个要注意的地方,就是必须增加两个反斜杠,这是因为是在c#中,一个反斜杠是用来表示转义字符,两个反斜杠才是真正的一个反斜杠(\).如果你是在配置文件中添加字符串因为不是c#代码,所以只需要一个反斜杠了。
连接数据库(cnn.open())
打开连接后应尽早将其关闭,以提高网站的性能
定义命令
定义命令时是要注意,虽然这一点没有关闭数据库连接那么重要,但是还是建议析构命令对象。
下面介绍两种连数据库的方法:
1、 直接连接数据库
这种连接方式和传统的ado编程方式和相近,并且它允许你防止潜在的“同时发生”的问题发生。用这种简单的数据连接,数据不连接备份是没有保留的。这就意味着你数据选择和数据修改必须分开来进行。你的程序必须追踪需要提交给数据源改变的数据。以下是简单连接数据库的方法
a) 创建connection.command,datareader对象
b) 用datareader从数据库获取信息,并且在一个web 表单上用一个控件显示它。
c) 关闭你的连接
d) 将这个网页发送给用户。在这里 ,用户看到的信息和数据库的的信息不再有任何联系,并且所有的ado.net对象都被销毁了
如果要增加和更新信息,做你下几步:
e) 创建connection 和command对象
f) 执行这个commmand
在这里我们需要导入两个名空间,如果我们是使用sql server 就导入如下两个名空间: System.data 和 System.data.sqlclient
这里还一点要注意的是在使用sql语句如果是动态生成sql语句,建议使用parametereized command防止黑客登陆,parameterized使用方法如下:
如果我们插入一条记录
String insertsql = Insert into user(username,password) values(@user,@pwd);
创建command对象sqlcommand cmd=new sqlcommand(insertsql,con);
增加参数 cm.parameters.addwithvalue(“@user”,txtusername.txt);(假设是从textbox中得到)
cmd.parameters.addwithvalue(“@pwd”,txtpwd.text);
2、 无连接数据连接
当无连接数据连接时,当你的代码在运行时数据会在你内存中留一份内存。使用dataset可以做到这一点,通过dataset和可以在其中建立表之间的关系,不过不是通过直接从数据库中得到,而是自己通过代码在程序中手动添加。(通过使用datarelation来创建)
比如创建pubs数据库中的titles 和titleAuthor之间的关系,
这里dspubs是从数据库读出来的dataset,其中包含两个表titles,titleauthor.
DataRelation titles_titleauthor = new datarelation (“titles_titleauthor”,
dspubs.tables[“titles”].columns[“title_id”], dspubs.tables[“titleauthor”].columns[“title_id”]);
在将这个关系加入到dataset中。
Dspubs.relations.add(title_titleauthor);
剩下来通过循环读取记录,可以通过relation来读取记录,读取过程如下:
1、 首先从author中将第一条记录读取出来
2、 然后使用authors_titleAuthor的关系,找到这个作者相应的子记录(这里描述关系型数据库中表与表之间的关系可以是1对多,多对1,多对多,像1对多也可以说成是父子关系),这一步通过使用DataRow中的GetChildRows方法来获得。
3、 对于每一个在titleauthor中获得的匹配记录,查询对应得title.这一步通过使用datarow的GetParentRows()来获得。
4、 移到下一条记录,重复上面的过程。代码见(P559)
注意:用关系要注意一点,如果你往子表中插入一条新的记录,但是他没有相应的父记录,那么ado.net会产生一个错误。类似的,你不能删除一个有孩子记录的父记录。这些限制在数据库中也是强制执行的。
修改无连接数据
在无连接数据中所做的任何修改不会自动更新到数据源中,比如你在dataset中做了修改,你需要自己增加额外的程序来将数据更新到数据库中。事实上,当你使用delete方法删除,这一行并没有真正删除,它只是标记为deletion状态
增加信息到dataset中
可以通过使用rows集合中的add方法将一新行加入到rows集合中。但是在你增加一新行之前你需要使用newrow方法得到这个新行的空白拷贝(拷贝其字段及字段属性)
更新无连接数据
这就是将dataset中的数据更新到数据库中,可以使用ado.net中的特性类:
commandBuilder对象,如果使用sql provider,这个类就是SqlCommandBuildr。
CommandBuilder对象检查你过去用来创建dataset的dataadapter,并且向其中加入额外的commmand对象,比如:insertcommand,DeleteCommand,UpdateCommand。
使用如下方法配置dataAdapter
SqlCommandBuilder build=new SqlCommandBuilder(dataApapter)
//返回一个更新后的dataAdapter
dataAdapter=cb.DataAdapter;
接着你就可以使用配置过的dataAdapter
如果你要使用这个 通过调用update()方法,如果你要更新多个表的话,你要为每一个表创建独立的dataAdapter..
Dataset存储了所有行的当前状态信息和他们原始状态。所以这就允许ado.net找到这个相应的改变行。他会增加每个新行(是标记为DatasetRowState.Add状态的)到DataAdapter.InnsertCommand中,同理其他的操作。