什么是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要知道的东西的更多相关文章

  1. Ado.net[登录,增删改查,Get传值,全选,不选,批量删除,批量更新]

    [虽然说,开发的时候,我们可以使用各种框架,ado.net作为底层的东西,作为一个合格的程序员,在出问题的时候我们还是要知道如何调试] 一.增删改查 cmd.ExecuteReader();执行查询, ...

  2. LinQ to sql简介及增删改查

    Linq to sql 类 LinQ它就是一个集成化的数据库访问类,它会自动生成许多原本需要我们自己创建的东西: 它和ADO.NET是一样的东西,都是为了访问数据库而出现的,EF框架 一.创建LinQ ...

  3. 对于大型公司项目平台选择j2ee的几层认识

    我是一个从野路子上一路走来的程序员,现在主要用.net做方案.选.net不选jave并没有什么特别的原因,只不过是因为我自己从c,java学起,后来被vs这个工具所吸引, 很熟悉这个平台罢了,从业15 ...

  4. ODBC、OLE DB、 ADO的区别

    转自:http://blog.csdn.net/yinjingjing198808/article/details/7665577 一.ODBC ODBC的由来 1992年Microsoft和Syba ...

  5. 分享一个html+js+ashx+easyui+ado.net权限管理系统

    EasyUI.权限管理 这是个都快被搞烂了的组合,但是easyui的确好用,权限管理在项目中的确实用.一直以来博客园里也不少朋友分享过,但是感觉好的要不没源码,要不就是过度设计写的太复杂看不懂,也懒得 ...

  6. 我与ADO.NET二三事

      天气渐冷,闲来无事就把业余时间自己使用的数据访问库凉一凉.这个库本人自己使用了2年多,主要用于个人学习时需要操作数据库时使用,非组织和商业性质的使用.记得上学的时候,在网络上看到SqlServer ...

  7. 第二天 ado.net, asp.net ,三层笔记

    1. ado.net步骤:     一:倒入命名空间      using System.Data;      using System.Data.sqlclient;     二:第一个模型 int ...

  8. 来科普下游标(MSSQL)这东西。。。

    刚刚接到一个面试电话,对头的先生问我懂不懂触发器和存储过程,当时是觉得有些好笑,毕竟“视图.触发和存储”是咱数据库工程师的吉祥三宝,怎么可能不认识?只是稍后他还问了下游标这东西,仔细想想我是不常使用C ...

  9. Microsoft SQL Server Compact 4.0&&ADO.NET Entity Framework 4.1&&MVC3

    最近重新查看微软MvcMusicStore-v3.0的源代码,发现忽略了很多重要的东西,特别是数据访问那一部分. 首先Microsoft SQL Server Compact 4.0 详细的介绍和下载 ...

随机推荐

  1. 分布式缓存Memcached

       分布式缓存服务器,既然用到数据缓存很明显就是想高效性的获取数据,大容量的存储数据.为了可以缓存大量的数据以及可以高效获取数据,那么分布式缓存数据库就要解决数据可以水平线性扩展,这样可以扩大数据容 ...

  2. metaq

    MetaQ(全称Metamorphosis)是一个高性能.高可用.可扩展的分布式消息中间件,思路起源于LinkedIn的Kafka,但并不是Kafka的一个Copy.MetaQ具有消息存储顺序写.吞吐 ...

  3. Pintos修改优先级捐赠、嵌套捐赠、锁的获得与释放、信号量及PV操作

    Pintos修改优先级捐赠.嵌套捐赠.锁的获得与释放.信号量及PV操作 原有的优先级更改的情况下面没有考虑到捐赠的情况,仅仅只是改变更改了当前线程的优先级,更别说恢复原本优先级了,所以不能通过任何有关 ...

  4. Qt 按键长按的处理

    keyPressEvent()部分代码: if (e->key() == Qt::Key_A && e->isAutoRepeat()) {   if (!mPressFl ...

  5. ABAP字符串按长度拆分

    REPORT ytest_012 MESSAGE-ID oo. ) TYPE c. ) TYPE c. ) TYPE c. DATA: l_pos TYPE i. DATA: BEGIN OF ls_ ...

  6. Notes of the scrum meeting(11/2)

    meeting time:13:00~13:30p.m.,November 2nd,2013 meeting place:3号公寓楼一层 attendees: 顾育豪                  ...

  7. makefile常用函数

    标签(空格分隔): makefile 1.字符串替换和分析函数 $(subst from,to,text) #在文本"text"中使用"to"替换每一处&quo ...

  8. WinForm-利用Anchor和Dock属性缩放控件

    转自:http://www.cnblogs.com/tianzhiliang/articles/2144692.html 有一点让许多刚接触WinForms编程的开发者感到很棘手,就是在用户调整各种控 ...

  9. Jenkins-测试自动化环境搭建(Python+RobotFramework+selenium)

    下载插件: Python:https://wiki.jenkins-ci.org/display/JENKINS/Python+Plugin RobotFramework:https://wiki.j ...

  10. ubuntu重置root密码

    from: http://mmicky.blog.163.com/blog/static/150290154201398113034698/ 使用ubuntu的时候忘记了root密码该如何重置?我使用 ...