码迷,mamicode.com
首页 > Web开发 > 详细

Ado.Net要知道的东西

时间:2014-07-07 20:24:26      阅读:299      评论:0      收藏:0      [点我收藏+]

标签:des   http   使用   strong   文件   数据   

什么是ADO.NET?

  ADO.NET就是一组类库,这组类库可以让我们通过程序的方式访问数据库,就像System.IO下的类用类操作文件一样,System.Data.这组类是用来操作数据库(不光是MSSql Server),它提供了统一的编程接口让操作其它数据库(Access、Oracle等)的方式和操作MSSql Server一致。

Ado.net目的:通过程序访问数据库。

Ado.Net组成:

  数据提供程序(常用类)

  Connection,用来连接数据库;

  Command,用来执行SQL语句;

  DataReader只读、只进的结果集,一条一条读取数据(StreamReader、XmlReader微软的类库中这些Reader的使用方式都差不多);

  DataAdapter,一个封装了上面3个对象的对象;数据集(DataSet),临时数据库,断开式数据操作。

其它常见类:

  ConnectionStringBuilder//自动生成连接字符串;

  Parameter//带参数的SQL语句;

  Transaction//在ADO.NET中使用事务;

与DataSet相关的类:

  DataView//视图类,DataTable中的数据以不同的视角查看

  DataRowView//DataView中的行。

  DataTable //DataSet中的数据表

  DataRow//DataTable中的行

  DataColumn//DataTable中的列

  DataRealation//DataTable与DataTable的关系

  Constraint//DataTable中建立的约束       

Ado.Net访问数据的方式:

(1)

  1.连接数据用Connection

  2.执行SQL语句Command

  3.执行完毕之后将结果一条一条返回。DataReader

(2)

  使用DataAdapter+DataSet,这种方法本质还是通过Connection、Command、DataReader将数据全部取出来然后放到了DataSet中。//看DataAdapter的构造函数。

Connection

 如何让应用程序与数据库建立连接?

  Connection对象。Connection就像读取数据库数据之前先要创建一条路,在读取Sql Server数据库使用。

连接数据的步骤:

  • 创建SqlConnection对象
  • 获取连接字符串
    • VS视图-服务器资源管理器-数据库连接上点右键-添加连接在新添的数据库上点右键属性里有连接字符串
    • 使用SqlConnectionStringBuilder帮助获取连接字符串
    • 使用PropertyGrid控件的SelectedObject属性与SqlConnectionStringBuilder配合使用。
  • 打开连接.(只能打开一次,可以多次关闭。测试是否打开时可以使用:ConnectionState枚举)
  • 关闭连接//相当于设置了路障
  • 释放资源//相当于把路拆了,这块地可以盖楼了。
    • 调用Connection.Dispose()【继承自Component类的方法】方法时,内部调用了Close()
    • connection不能重复打开。

  连接池:InnerConnection。用连接池打开连接:Data Source=.\\sqlexpress;Initial Catalog=MySchool;IntegratedSecurity=True;

  ADO.Net中通过SqlConnection类创建到SQLServer的连接,SqlConnection代表一个数据库连接,ADO.Net中的连接等资源都实现了IDisposable接口,可以使用using进行资源管理。

  sqlconnection在程序中一直保持它open可以吗?

  对于数据库来说,连接是非常宝贵的资源,一定要用完了就close、dispose。【Close以后就可以放到“池”中了,其他链接就可以再次使用了。】

Command

  操作Sql Server数据库使用SqlCommand对象,SqlCommand表示向服务器提交的一个命令(SQL语句等) , CommandText属性为要执行的SQL语句.

创建SqlCommand对象:

  1.通过new关键字创建

  2.通过IDbConnection.CreateCommand()方法创建(编写通用代码的时候使用(多态))

常用的三个方法:

  ExecuteNonQuery()        执行对数据库的增删改,返回受影响的行数,适合:insert、delete、update(对于其他语句返回-1)

  ExecuteScalar()       执行查询,返回首行首列

  ExecuteReader()     执行查询,返回DataReader对象

  StatementCompleted事件:

  每条SQL语句执行完毕之后触发。多条语句同时执行(用分号隔开),如何获取每条语句所影响的行数?//实际返回值为每条语句所影响的行数的和。

ExecuteScalar

  SqlCommand的ExecuteScalar方法用于执行查询,并返回查询所返回的结果集中第一行的第一列,因为不能确定返回值的类型,所以返回值是object类型

  得到自动增长字段的主键值,在values关键词前加上output inserted.Id,其中Id为主键字段名。执行结果就试插入的主键值,用ExecuteScalar执行最方便。(output语句使用的是inserted、deleted两个临时表)

  cmd.CommandText =“insert into class(cName,cDescription) output inserted.classId values(‘高三一班’,‘描述’)”;int i = Convert.ToInt32(cmd.ExecuteScalar());

  原来的写法:

  cmd.CommandText =“insert into class(cName,cDescription) values(‘高三一班’,‘描述’);select @@identity”;int i = Convert.ToInt32(cmd.ExecuteScalar());@@IDENTITY 可以返回当前会话中的所有表中生成的最后一个标识值。

执行查询

  执行有多行结果集的用ExecuteReader。

  SqlDataReader reader = cmd.ExecuteReader();...

  while (reader.Read()){Console.WriteLine(reader.GetString(1));}

  reader的强类型的GetString()、GetInt32、GetFloat()、GetDouble()等方法只接受整数参数,也就是序号,用GetOrdinal方法根据列名动态得到序号,更简单的方法reader[‘uUserName’]。

  使用reader根据列索引读取列数据而不是列名(列名最后也转化为索引);//一般如果没有特殊情况建议使用索引来获取列信息,不要使用列名(效率较 低)。//根据列名来获取数据的话,比较好的写法是:int c1=reader.GetOrdinal("lie1");object obj1=reader[c1]; reader.GetDataTypeName()//当前列的数据类型。

  为什么用using?

  Close:关闭以后还能打开。Dispose:直接销毁,不能再次使用。using在出了作用域以后调用Dispose,SqlConnection、SqlDataReader等的Dispose内部都会做这样的判断:判断有没有close,如果没有Close就先Close再Dispose。

  DataReader的HasRow实现://判断如果close,则直接抛出异常。

  public override boolHasRows { get { if (this.IsClosed) { throw ADP.DataReaderClosed("HasRows"); } return this._hasRows; } }

  注意:DataReader必须独享一个Connection 。 (除非设置了允许MARS,多活动结果集,在连接字符串中)。

SqlDataReader使用注意事项

  返回reader后数据在哪里?数据库服务器缓存

  当使用DataReader的时候必须保证Connection为Open状态;

  reader只读(不能通过reader修改数据。)、只进;reader每次读取一条就释放一条所以只能向前不能后退;

  由于功能有限,所以读取速度很快,适合从数据库中读取大量数据;  

  HasRow属性返回是否有行。IsDbNull()判断数据是否为null;

  数据库中的类型与C#的不太一样,数据库中的float,得用c#的GetDouble()来获取

  如果返回多个结果集则使用NexResult()方法。通过do-while循环测试。强类型转换时,需要使用IsDbNull()判断获得的数据是否为空。

  通过执行ExecuteReader()方法获取输出参数的时候需要将reader.Close()以后才能获取。

Ado.Net连接池

  由于每次正常连接数据库都会至少执行3个操作(1.登录数据库服务器2.执行操作3.注销用户),所以每次通过Connection向数据库服务器申请一个连接都比较耗时。【ado.net默认启用了连接池】。

如何清空连接池?Connection的静态方法ClearAllPools()、ClearPool()。

什么情况下需要禁用连接池?

  一般都不禁用。尤其是asp.net之类的程序,n多个用户频繁访问,但是大多数用户访问时采用的都是同一个连接字符串。但如果某个应用程序有多个客户端,每个客户端访问时采用的都是各自的连接字符串,这时如果采用连接池,虽然每次打开连接的速度会变快,但是由于“池”的问题同时会保存多个打开的连接对象。

注意:一般一个项目中常用的连接也不过几个而已。

Ado.net连接池使用总结:

  1.第一次打开连接会创建一个连接对象。

  2.当这个连接关闭时(调用Close()方法时)会将当前那个连接对象放入池中。

  3.下一个连接对象,如果连接字符串与池中现有连接对象的连接字符串完全一致(大小写敏感),则会使用池中的现有连接,而不会重新创建一个。

  4.只有对象调用Close(),的时候才会放入池中,如果一个连接对象一直在使用,则下次再创建一个连接对象发现池中没有,也会再创建一个新连接对象。在池中的连接对象,如果过一段时间没有被访问则自动销毁。

查询参数

  SQL语句使用@ParameterrName表示“此处用参数代替”,向SqlCommand的Parameters中添加参数。参数在SQLServer内部不是简单的字符串替换,SQLServer直接用添加的值进行数据比较,因此不会有注入漏洞攻击。(带参数的sql语句内部是调用了存储过程)。

  带参数的一个问题(小bug):

  SqlParameter p1=new SqlParameter("@age",0);//只有0会出现意外的问题。当是0的时候会调用另一个重载:SqlParameter(string parameterName,SqlDbType dbType);在0前加object,即有重载对象可以应用。

DataSet(ado.net断开式数据访问)

  DataSet是什么?

  数据的集合、临时数据库、内存数据库。(B/S程序与C/S程序对DataSet的不同处理方式)。

  DataSet和SqlDataReader的对比:

  SqlDataReader是连接相关的,SqlDataReader中的查询结果并不是放到程序中的,而是放在数据库服务器中,SqlDataReader只是相当于放了一个指针(游标),只能读取当前游标指向的行,一旦连接断开就不能再读取。这样做的好处就是无论查询结果有多少条,对程序占用的内存都几乎没有影响。

SqlDataReader为速度而生,只读、只进,功能有限。ADO.Net中提供了数据集的机制,将查询结果填充到本地内存中,这样连接断开、服务器断开都不影响数据的读取。

  DataSet对于多层应用程序之间传递数据。(现在大都用List<T>)

  语句:DataSet dataset = new DataSet(); SqlDataAdapter adapter = new SqlDataAdapter(cmd); adapter.Fill(dataset);

  SqlDataAdapter是DataSet和数据库之间沟通的桥梁。数据集DataSet包含若干表DataTable,DataTable包含若干行DataRow。foreach (DataRow row in dataset.Tables[0].Rows) row["Name"]。

  可以使用不同的SqlDataAdapter来更新DataTable,如果要是用SqlCommandBuilder自动生成的Command对象的话,必须提供selectCommand,但是可以不用Fill。

  1. 什么是DataSet?

  数据集合、临时数据库、内存数据库。但DataSet是通过DataReader填充的。

  2.通过DataAdapter填充DataSet,Fill()也可以分页(并不高效,会在服务器端都把数据查询出来,然后用DataReader跳过前面的数据,只取后面要的数据,真正的分页应该是在数据库中就只查询出当前页的数据。)

  3.断开式数据访问,操作完成以后调用Update()方法。

  DataSource可以绑定什么类型的数据?

  IList接口,包括一维数组。IListSource接口,例如,DataTable和DataSet类。IBindingList接口,例如,BindingList(T) 类。IBindingListView接口,例如,BindingSource类。

注意点:

  1.通过DataAdapter的Fill方法填充DataSet中的表。

  2.创建DataAdapter的时候,只需指定连接字符串和查询语句,会自动生成SelectCommand。

  3.通过SqlCommandBuilder自动创建InsertCommand、DeleteCommand、UpdateCommand,然后就可以调用adapter的Update()方法将     DataTable中的数据更新到数据库中。

    3.1通过SqlCommandBuilder来创建Command对象的时候,必须保证在创建adapter的时候的select语句中包含对主键的查询

  4.也可以自己指定Command,我们对DataTable的操作,只是为Rows集合中没行的RowState状态做了标记,并没有将该行从Rows集合中真的删    除。

多条件搜索时Where 1=1

  当拼接多个where条件时,有时候不知道and|or前面的条件是否存在。往往会在后面跟一个where 1=1,但这种方法并不高效。如果使用这种方式,在数据库中会坐全表扫描(对每行数据都进行扫描,比对。),会无法使用索引等优化查询的策略。且建的索引将会失效。

  解决方法:List+string.join

Ado.Net中的存储过程

//通过连接对象创建一个事物

SqlTransaction tran=con.BeginTransaction();

Tran.commit();//提交事务

Tran.rollback();//回滚事务

 

 

Ado.Net要知道的东西,布布扣,bubuko.com

Ado.Net要知道的东西

标签:des   http   使用   strong   文件   数据   

原文地址:http://www.cnblogs.com/anlen/p/3813241.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!