目录:

  1. 简单的介绍下ADO.NET
  2. SqlConnection(连接对象)
  3. SqlCommand(命令对象)
  4. SqlParameter(Sql参数)
  5. SqlDataReader(数据流读取器)
  6. SqlTransaction(事务)
  7. SqlDataAdapter(数据适配器)
  8. DataSet,DataTable,DataRow,DataColumn
  9. 封装数据库操作类(这才是精华)

一丶简单的介绍下ADO.NET

  了解System.Data命名空间下我们常用的一些类:

 1 ①System.Data  → DataTable,DataSet,DataRow,DataColumn,DataRelation,Constraint,DataColumnMapping,DataTableMapping
2 ②System.Data.Coummon → 各种数据访问类的基类和接口
3 ③System.Data.SqlClient → 对Sql Server进行操作的数据访问类
4 主要有: a) SqlConnection → 数据库连接器
5 b) SqlCommand → 数据库命名对象
6 c) SqlCommandBuilder → 生存SQL命令
7 d) SqlDataReader → 数据读取器
8 e) SqlDataAdapter → 数据适配器,填充DataSet
9 f) SqlParameter → 为存储过程定义参数
10 g) SqlTransaction → 数据库事物

二丶SqlConnection(连接对象)

  1.连接字符串

    基本语法:数据源(Data Source)+数据库名称(Initial Catalog)+用户名(User ID)+密码(Password)(这种方式比较安全)!

    推荐文章 :SQL Server 连接字符串和身份验证你必须知道的ADO.NET(三) 连接字符串,你小觑了吗?SQL Server 2008连接字符串写法大全,连接字符串有很多的写法,最保险的写法可以借助“SqlConnectionStringBuilder”类,它提供了全面的连接字符串的属性,以至于减少出错率(相关属性查MSDN),还有大多数连接字符串都写在配置文件里面了!

  2.创建连接对象

  3.打开和关闭连接对象(使用Using来关闭连接)

    关于连接池的文章:你必须知道的ADO.NET(五) 细说数据库连接池(写的还真不赖啊),顶...

 三丶SqlCommand(命令对象)

  1.实例化的时候默认初始化的四个属性

  2.创建命令对象

    使用连接对象的“CreateCommand()”方法创建命令对象,也可以使用new来实例化对象!

1 SqlCommand command = connection.CreateCommand(); //这种方式比较好,也可以自己实例化一个对象!

  3.几个重要属性

    ①CommandText:获取或设置要对数据源执行的 Transact-SQL 语句、表名或存储过程!

    ②CommandType:设置你执行的SQL语句是存储过程还是T-SQL(是一个枚举)!

    

    ③Parameters:设置你T-SQL中你需要用到的参数(后面会讲到),是一个“SqlParametersCollection”类型,这个属性很重要,是你通过代码给SQL语句传递参数的途径,所以记住语法,记住一些使用规则讲对编码有很大的帮助!

  4.几个重要的方法(相信大家熟悉的不能再熟悉了)

    ①ExecuteNonQuery:返回是影响的行数(int),主要执行更新,添加,删除等操作!

    ②ExecuteReader:执行SQL或存储过程,返回的是SqlDataReader类型,主要用来查询!

      ★  这边注意这个方法的重载 CommandBehaviour 枚举,成员如下:

    

1 command.ExecuteReader(CommandBehavior.CloseConnection); //在执行读取之后会自动关闭连接对象

    ③ExecuteScalar:返回执行结果集中的第一行第一列,如果没有数据,则返回NULL!

     Note:因为可能会返回“Null”值,所以需要对结果进行判断,如下:

    ④CreateParameter:创建SqlParameter实例

1 SqlParameter para = cmd.CreateParameter() //此方法适合SQL语句中只有一个参数的情况!

    推荐文章:你必须知道的ADO.NET(六) 谈谈Command对象与数据检索

          你必须知道的ADO.NET(七) Wow!Command对象高级应用

四丶SqlParameter(Sql参数)

  1.几个重要的属性    

  ParameterName:   设置参数名

  Value:              给参数设置值

    Size:                 设置参数字节最大大小(以字节为但为)

    SqlDbType:     参数在SQL中的类型  

  2.命令对象添加参数集合的几种方法

    ①AddWithValue

    ②Add

    ③AddRange

    推荐文章:SqlParameter的作用与用法,代码如下:

 1  using (SqlConnection connection = new SqlConnection(""))
2 {
3 SqlCommand command = connection.CreateCommand();
4 command.CommandText = "";
5
6 //可以使用这种方式添加多个参数,不过方式不够好
7 command.Parameters.Add("@name", SqlDbType.NVarChar).Value = "yang"; //第一种方式
8 command.Parameters.Add("@age", SqlDbType.Int).Value = 888;
9 command.Parameters.Add("@address", SqlDbType.NVarChar, 100).Value = "Jiang Su";
10
11 //这种方式直接给定参数名和参数就可以了,可操作性比较差
12 command.Parameters.AddWithValue("@name", "yang");
13 command.Parameters.AddWithValue("@age", 888).SqlDbType = SqlDbType.Int;
14 command.Parameters.AddWithValue("@address", "Jiang su").SqlDbType = SqlDbType.NVarChar;
15
16 //直接使用参数集合添加你需要的参数,推荐这种写法
17 SqlParameter[] parameters = new SqlParameter[]
18 {
19 new SqlParameter("@name",SqlDbType.NVarChar,100){Value = "yang"},
20 new SqlParameter("@age",SqlDbType.Int,2){Value = 888},
21 new SqlParameter("@address",SqlDbType.NVarChar,20){Value = "Jiang Su"},
22 };
23 command.Parameters.AddRange(parameters); //参数也可以是一个Array数组,如果采用数组参数代码的可读性和扩展性就不是那么好了
24
25 //当我们把参数都添加好之后,会生成一个“SqlParameterCollection”集合类型,相当于参数的集合
26 //那么我们就可以对这些参数进行修改和移除了
27 //说穿了“SqlParameterCollection”内部其实是一个List<SqlParameter>的集合,只是它里面的复杂度比较高,考虑的很全面
28 command.Parameters[0].Value = "hot girl";
29 command.Parameters[0].Size = 200;
30 }

  3.说说“SqlParameterCollection”,参数集合

    上面添加的“SqlParameter”参数都被添加到了“SqlParameterCollection”集合中去了,所以我们才能够对它进行读取和修改!

  4.定义适当的参数属性获取存储过程的返回值(return) → Direction = ParameterDirection.Output

    代码如下:

五丶SqlDataReader(数据流读取器)

  说实话,如果单单知道怎么使用读取器,那是非常好学的,如果深入了解,它里面的知识将会非常的吸引人,那么就以我小菜的经验来说说把,各位不要见怪啊!

  1.基本用法

  2.常用方法

    ①GetOrdinal:获取指定列名的列序号(索引号),使用这个方法可以把经常变动的列进行固定

1 int name = dr.GetOrdinal("name"); //通过列名来获取当前列的索引号,这样如果下次你列名顺序发生变化也没有关系

    ②GetName:  获取列名,参数为指定列名的序列号,返回string

1 string columnName = dr.GetName(name); //通过列名所处的索引号来获取列名名称 

    ③IsDBNull:判断当前读取的数据是否为Null,返回类型为Bool     

1   dr.IsDBNull(coContactID) ? "NULL" : dr.GetInt32(coContactID).ToString() //相信大家都会使用的

    ④NextResult:当查询为批处理查询时,使用这个方法去读取下一个结果集,返回值为Bool,如果存在多个结果集,则为 true;否则为 false

1 //select * from Employee;select * from County,这样的话就可以采用这种方式
2 dr.NextResult(); //记住这个要放在while(dr.Read())之后,因为读取一个数据集之后才能读取下一个数据集 

    ⑤Read:读取数据

      读取数据最重要的方法,不说了!

  3.常用属性

    ①HasRow:判断是否包含一行或多行,也就是判断有没有数据,返回类型为Bool

    ②FieldCount:获取读取的列数,返回类型为Int

    ③IsClosed:判断读取的数据流是否关闭

      所以灵活运用上面的属性讲增强代码的可读性和健壮性,综合示例:

 

    Note:当 SqlDataReader 关闭后,只能调用 IsClosed 和 RecordsAffected 属性,如果调用其它方法或属性将会报错!

  4.性能深入剖析

    读取数据的时候会有很多种写法,如dr[0].ToString(),dr["Name"].ToString(),dr.GetString(0),dr.GetSqlString(0)等等的读取方式的写法,如果大家去网上查资料就会很容易发现这几种写法存在着一些差异!

    下面是读取数据性能的总结:

1     SqlDataReader读取方法:
2 1. DataReader 索引 + 基于 [序列号] → dr[0].ToString | Index-based access
3 2. DataReader 索引 + 基于 [列名] → dr["Name"].ToString | 性能最差
4 3. Get 开头的 + 基于 [序列号] → dr.GetString(0) | type-access
5 4. GetSql 开头的 + 基于 [序列号] → dr.GetSqlString(0) | Provider-specific typed accessor
6 5. GetOrdinal() 通过列名获取这个列的序列号 | 这个方法在提高性能上面有作用
7 6. 性能(4) --> (3) --> (1) --> (2)

    Note:所以在对数据进行读取时要有针对的使用一些性能高的方法,也不是说要追求性能,只是这是一种习惯,对于大多数读取数据库的方法使用索引来读取无疑是最快,记住一句话,“当性能没有成为问题的时候,不要过度的去优化它”,高效而又优美的使用这些方法,才是王道!

    推荐文章:SqlDataReader 提前终止的性能问题

    PS:我这里的总结其实是以前在园子看到一个人写的,找了半个小时都没找到,如果有人看到过,发个链接给我,我补上!

  5.SqlDataReader和DataSet的讨论

    推荐文章:谈谈Asp.net网站优化一:SqlDataReader和DataSet的选择

六丶SqlTransaction(事务)

  1.代码中的事务    

    现在代码中基本使用存储过程来控制事务的处理,通过代码进行控制事务也是我们学习ADO.NET的任务之一!

    事务是在连接对象之后创建,并把它跟命令对象进行关联,使用try.....Catch捕获异常,然后调用RollBack方法回滚事务!

    Commit:提交

    RollBack:回滚

  2.事务中的命名存储点      

    一旦你定义了命名存储点,只能回滚命名存储点之后的操作,这是要是情况而使用!

    这种情况是当你调用RollBack方法并重载一个命名存储点的参数,如下代码所示:

 1     using (SqlConnection conn = new SqlConnection(str))
2 {
3 conn.Open();
4 SqlTransaction transaction = conn.BeginTransaction();
5 SqlCommand cmd = conn.CreateCommand();
6 cmd.CommandText = "";
7 cmd.Transaction = transaction;
8 //使用命名存储点
9 transaction.Save("this is point"); //定义命名存储点,使用Save方法先保存存储点,定义回滚数据的开始位置
10
11 //这边是你要回滚的操作代码,TO DO...
12
13 //把从命名存储点到这里的操作进行回滚
14 transaction.Rollback("this is point"); //回滚命名存储点
15 }

  3.SQL语句中的事务(SQL Server中的事务其实很复杂的)

1 BEGIN TRANSACTION
2
3 --你需要执行的更新,删除,插入的语句
4
5 IF(@@ERROR > 0) //这是系统变量,存储你在执行更新,删除,插入操作时发生错误的记录编号
6 ROLLBACK
7 ELSE
8 COMMIT

    推荐文章:浅谈SQL SERVER中事务的ACID

          深入sql server中的事务

  4.说说“TransactionScope”,让事务更加的简单 

 1 using (TransactionScope transactionScope = new TransactionScope())
2 {
3 try
4 {
5 using (SqlConnection connection = new SqlConnection())
6 {
7 // TO DO
8 //提交事务,如果有异常,他会自动回滚的
9 transactionScope.Complete();
10 }
11 }
12 catch (Exception)
13 {
14 //捕获异常
15 throw;
16 }
17 }

    推荐文章:C#综合揭秘——细说事务

七丶SqlDataAdapter(数据适配器)

  1.构造函数 

1 四个重载:
2 1. 无参
3 2. SqlDataAdapter(SqlCommand) → 执行命令对象实例
4 3. SqlDataAdapter(String, SqlConnection) → ①只能指定查询语句 ②连接对象实例
5 4. SqlDataAdapter(String, ConnectionString) → 用 SelectCommand 和一个连接字符串初始化 SqlDataAdapter 类的一个新实例
6 Note:第四个重载就把连接对象和命令对象都包含进去了!

  2.填充数据(Fill)

    最简单的填充数据

1 DataSet dataSet = new DataSet();
2 using (SqlConnection conn = new SqlConnection(""))
3 {
4 conn.Open();
5 SqlCommand command = conn.CreateCommand();
6 command.CommandText = "select name,age,address from MyInformation";
7 SqlDataAdapter dataAdapter = new SqlDataAdapter(command);
8 dataAdapter.Fill(dataSet); //填充数据
9 }

  3.使用“SqlCommandBuilder”对数据进行增删改查

    ①添加数据

 1  using (SqlConnection conn = new SqlConnection(ConnectionString()))
2 {
3 conn.Open();
4 //构建查询语句,也可以指定SqlCommand,其中变换的方法有很多
5 SqlDataAdapter da = new SqlDataAdapter("select LastName,FirstName from dbo.Employees", conn);
6 DataSet ds = new DataSet();
7 da.Fill(ds);
8 //这句话很重要,它会把你在DataSet增加的数据转化为SQL语句用来更新数据库
9 SqlCommandBuilder cmdBuilder = new SqlCommandBuilder(da);
10 //添加行,实例化一个行对象,注意是用NewRow来创建行
11 DataRow row = ds.Tables[0].NewRow();
12 row[0] = "Yang";
13 row[1] = "鬼头";
14 ds.Tables[0].Rows.Add(row); //添加到表中
15 da.Update(ds); //把DataSet中表和数据库进行对比,更新
16 }

    ②修改数据

 1 using (SqlConnection conn = new SqlConnection(""))
2 {
3 SqlDataAdapter da = new SqlDataAdapter("SQL语句或你自己定义的命令对象", conn);
4 DataSet ds = new DataSet();
5 da.Fill(ds);
6 //很重要的一句话
7 SqlCommandBuilder cmdBuilder = new SqlCommandBuilder(da);
8 ds.Tables[0].Rows[12][1] = ""; //修改数据
9 da.Update(ds);
10 //调用Update方法其中隐式的调用了AcceptChanges方法,更新数据集中的数据
11 //如果你继续使用这个数据集而没有调用这个方法,在后面的使用会出现异常
12 ds.AcceptChanges(); //这句话可以不写的
13 }

    ③删除数据

 1  using (SqlConnection conn = new SqlConnection(""))
2 {
3 SqlDataAdapter da = new SqlDataAdapter("SQL语句或你自己定义的命令对象", conn);
4 DataSet ds = new DataSet();
5 da.Fill(ds);
6 SqlCommandBuilder cmdBuilder = new SqlCommandBuilder(da);
7 //删除数据
8 ds.Tables[0].Rows[12].Delete();
9 da.Update(ds); //这边会隐式调用DataTable的AcceptChanges方法
10 }

    Note(很重要的注意点):值得注意的是Update方法已经隐式帮我调用了AcceptChanges,不比担心状态为改变删除数据会报错,微软已经帮我们都做好了,其实背后就是做的Table.AcceptChanges()这件事,如果在一般的DataTable中会怎么样,提交自上次调用 AcceptChanges 以来对该行进行的所有更改,在调用这个方法之后,表中所有更改将会提交,所有行状态(RowState)状态都将变为Unchanged,在DataSet中我将会说到这些内容!

  4.关于“SqlDataAdapter”中Fill方法的一些讨论

    简单的写一下,MSDN上都有的,查一下就知道了!

1 ★指定填充数据的数量,如:
2 //从第五行到第十行数据填充DataSet
3 //上面的定义错了
4 //应该是从第六行开始,后面的十条记录
5 da.Fill(ds,5,10,”MyTable”)

八丶DataSet,DataTable,DataRow,DataColumn

  表示数据存放在缓存中,DataSet里面可以包含多个DataTable,DataTable中有多个DataColumn和多个DataRow,包括对各种对DataTable的操作,以及对列和行的操作,在进行DataSet,DataTable进行操作的时候,应该先判断它们是否为Null,这是最基本的!

  1.DataTable,DataRow,DataColumn

    ①创建自己的DataTable

    ②使用对象集合初始化器简化代码,以及使用“DataColumnCollection”和“DataRowCollection”来操作已添加的行和列

    构造函数的访问修饰符为Internal,通过这两个集合可以对Column和Row进行“增,删,改,查”,详细见MSDN,如Remove,Add,RemoveAt etc!

 1 dt.Columns.Add(new DataColumn("Age", typeof(Int32)));
2 dt.Columns.Add(new DataColumn()
3 {
4 ColumnName = "Address",
5 DataType = typeof(string),
6 DefaultValue = "江苏海安"
7 });
8 //我们这边使用Add的方法的第二个重载
9 dt.Rows.Add(new object[] {"11", 44, "222", "yang cao gui"});
10 //我们也可以对添加好的行和列进行读取和修改
11 dt.Columns[0].ColumnName = "wang wei";
12 dt.Rows[0]["wang wei"] = "我把这行这列的值修改了,哈哈";

    ③使用表达树快速构建自己的列,详细的也可以查MSDN

  2.DataRowState(行状态),DataRowVersion(行版本)

    ①DataRowState(行状态)是“DataRow”中一个很重要的状态,主要有五个方面:

1     Added          → 添加
2 Deleted → 删除
3 Detached → 分离
4 Modified → 修改
5 Unchanged → 为改变

    

     Note如果实例化一个行,但没有加入到任何一个表中,那么它的状态永远是Detached,不存在Add,Modified之分,这个是要注意的!

    ②DataRowVersion(行版本),有四个版本状态,如下:

1     Current     → 最近的行,主要针对Deleted操作之前的行,行状态的Deleted
2 Default → 行的默认状态
3 Original → 行的原始值 Added,Modified,Unchanged
4 Proposed → 行的建议值

    

    PS:如果想理解它们,应该要写一些示例代码来模拟它们,这样就能很好的熟悉它们了!

    强烈推荐这篇文章:→ 深入.NET DataTable(写的很仔细,不错,一定要看的),还有这篇 → 深入.NET DataTable(补遗)

  3.DataSet,DataTable

    比较重要的方法:Select,Merge,Copy,Clone,GetChanges等等

    关于GetChanges方法:获取数据改变的地方,它所获取的是你上次调用AcceptChanges方法之后修改数据的信息,这点要注意了!

  4.下面是对DataSet和DataTable讲的比较好的文章收集  

    DataTable.Select使用小心得

    DataTable 深入解析数据源绑定原理之高级篇

    比较两个DataTable数据(结构相同)——5万条数据仅需几秒

  5.关于“DataRelation”和“DataView”的知识也很重要 

    DataView → 表示用于排序、筛选、搜索、编辑和导航的 DataTable的可绑定数据的自定义视图,看文章:DataSet,DataTable,DataView

    DataRelation → 表示两个 DataTable 对象之间的父/子关系,看文章:DataRelation(DataSet中父子表)的一个示例

九丶封装数据库操作类(这才是精华)

    只有充分理解了上面的知识,才能更好的封装,才能写出健壮的面向对象数据库操作类库,因本人知识有限,简单的封装还可以,但是不足以见人,所以收集了了一些好文章,供我们来学习:

    1.SqlHelper- -高悬的双刃剑(到底好用么~~) (提炼更加健壮的代码)

    2.我的DbHelper数据操作类(自定义操作类库)

    3.JSM SqlHelper 2.0 源码下载(封装的更细啦,有机会研究研究)

    4.微软原版SQLHelper类(代码太多,有很多我们会用不到,还有重载的也太多了吧!)

  好了就这么多了,想简单也很简单,想复杂登天还难,哈哈,还是看个人的选择把,园子里面这方面的文章也有很多,一搜一大堆,好好研究下就ok了!

结束:写了一个星期,终于搞完了,肯定还有很多地方没有涉及到的,大家多多指点...

最新文章

  1. shell--4.echo和printf
  2. 移动端头像上传AJax input file
  3. 【BZOJ 1178】【APIO 2009】CONVENTION会议中心
  4. [Android Pro] Android以root起一个process[shell脚本的方法]
  5. 备份U盘分区表,未雨绸缪
  6. Linux 网卡设备驱动程序设计(3)
  7. java的集合框架之一
  8. JVM调优总结(二)-一些概念
  9. Windows phone 8 学习笔记(1) 触控输入
  10. BP简单的理解神经网络
  11. 关于form表单上传图片的一些记录
  12. Docker 内核名字空间
  13. Cetos 7 系统安装备注事项
  14. ES6 必须要用的数组Filter() 方法,不要再自己循环遍历了!!!
  15. CSS学习笔记11 CSS背景
  16. Vsftp的PASV mode(被动模式传送)和Port模式及 Linux下VsFTP配置全方案
  17. datetime is not json serializable
  18. WPF 数据绑定 使用Code First with Database
  19. ip相关问题解答
  20. Scala安装时的坑

热门文章

  1. Maven本地仓库引入自定义/第三方的jar
  2. topcoder srm 320 div1
  3. 小白学习 Redis 数据库日记(2017-06-13)
  4. Python3 tkinter基础 Canvas delete 删除画布中的所有图形
  5. mysql的 深度使用 - 游标 , 定时器, 触发器 的使用 ?
  6. 大臣的旅费|2013年蓝桥杯A组题解析第十题-fishers
  7. 【安装】Matlab7.0简介及安装
  8. 浅谈Java中static关键字、权限修饰符
  9. Calculate difference between consecutive data points in a column from a file
  10. java核心问题总结