1.ADO.NET类库有三种不同的方式来实现数据访问:连接式、断开式、通过Entity框架(EF)
2.使用连接式,代码需要显示连接或者断开基层数据源,用这中方式使用ADO.NET时,通常会用到连接对象、命令对象、和数据读取器对象来实现数据交互。
3.数据提供程序是一组定义在用于和特定数据源类型进行通信的命名空间内的一组类型。每种提供程序都有一系列类来提供核心功能。
4.不同数据提供程序(如:SqlConnection和OracleConnection、MySqlConnection...),都有从相同的基类(如连接对象是DbConnection)继承并且实现相同的接口(如:IDbConnection)。
5.相关对象接口
IDbConnection接口
该接口定义了一系列用于配置某个数据库连接的一些成员,通过它,还能获取一个数据提供程序的事务对象。
IDbTransaction BeginTransaction();
IDbTransaction接口
提供事务处理能力
IDbCommand接口
命令对象实现该接口,让你以编程的方式处理SQL语句、存储过程和参数化查询。
int ExecteNoQuery();
IDataReader ExecuteReader();
IDbDataParameter和IDataParameter接口
让我们能够通过ADO.NET的参数对象来表示SQL命令和存储过程中的参数,而不是把这些参数硬编码在sql语句中。
IDbDataAdapter和IDataAdapter接口
数据适配器用来从特定数据库获取和返回DataSet.。相关属性保存实现相关的sql语句
IDbCommand DeleteCommand{get; set ;}
IDbCommand InsertCommand{ get; set; }
IDbCommand SelectCommand{ get; set; }
IDbCommand UpdateCommand{get ;set ;}
使用Fill()和Update()在调用者和基层数据库之间传递DataSet。
IDataReader和IDataRecord接口
IdataReader定义了数据读取器对象的一些常用行为,他能以只读向前的形式循环提取数据。
6.每个微软提供的数据提供程序都有一个继承自System.Data>common.DbProviderFactory的工厂类。该基类定义了一些方法来获取某数据提供程序的数据对象。
存在缺陷,必须调用基础程序的特殊成员,需要通过显示强制转化实现。
示例:
public class Class1
{
private string GetProviderString()
{
return ConfigurationManager.AppSettings["provider"];
}
private string GetConnectionString()
{
return ConfigurationManager.AppSettings["connStr"];
}
public void Start()
{
string provider = GetProviderString();
string cnStr = GetConnectionString();
DbProviderFactory sqlFactory = DbProviderFactories.GetFactory(provider);
using (DbConnection cn = sqlFactory.CreateConnection())
{
cn.ConnectionString = cnStr;
cn.Open();
DbCommand cmd = sqlFactory.CreateCommand();
cmd.Connection = cn;
cmd.CommandText = "select * from TB_Test";
using (DbDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
{
Console.WriteLine("Id is {0},Name is {1}", dr["Id"].ToString(), dr["Name"].ToString());
}
}
}
}
}
7.当前的配置在*.config文件的<appSettings>元素中,应用程序配置文件定义了一个新的元素<connectionStrings>。这个元素内设置任意多个名称/值对组合并能通过ConfigurationManager.ConnectionStrings索引器以编程方式访问。能够一统一的方式定义多个连接字符串。
如:return ConfigurationManager.ConnectionStrings["SQL Server Provider"].ConnectionString;
8.ADO.NET连接层
public void AdoConnLayer()
{
using (SqlConnection conn = new SqlConnection())
{
conn.ConnectionString = GetConnectionString();
conn.Open();
string sql = "select * from TB_Test";
SqlCommand cmd = new SqlCommand(sql, conn);
using (SqlDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
{
Console.WriteLine("Id is {0},Name is {1}", dr["Id"].ToString(), dr["Name"].ToString());
}
}
}
}
9.使用数据读取器获取多个结果集
public void AdoConnLayer()
{
using (SqlConnection conn = new SqlConnection())
{
conn.ConnectionString = GetConnectionString();
conn.Open();
string sql = "select * from TB_Test";
sql += (";" + "select * from TB_T1");
SqlCommand cmd = new SqlCommand(sql, conn);
using (SqlDataReader dr = cmd.ExecuteReader())
{
do
{
while (dr.Read())
{
Console.WriteLine("Id is {0},Name is {1}", dr["Id"].ToString(), dr["Name"].ToString());
}
} while (dr.NextResult());
}
}
}
10.参数化命令对象
/// <summary>
/// 针对特定的表结构使用参数化的命令对象
/// </summary>
public void Table1DoInsert(int Id, string Name)
{
string sql = string.Format("insert into Table1 values(@Id,@Name)");
using (SqlCommand cmd = new SqlCommand(sql, sqlCoon))
{
SqlParameter para = new SqlParameter();
para.ParameterName = "@Id";
para.Value = Id;
para.SqlDbType = System.Data.SqlDbType.Int;
cmd.Parameters.Add(para);
para = new SqlParameter();
para.ParameterName = "@Name";
para.Value = Name;
para.DbType = System.Data.DbType.String;
cmd.Parameters.Add(para);
cmd.ExecuteNonQuery();
}
}
参数化命令对象在使用存储过程时更好用。
/// <summary>
/// 执行存储过程
/// Proc_GetName
/// @Id int, @Name char(10) output
/// as
/// select @Name = Name from Table1 where Id = @Id
/// </summary>
public string GetNameById(int Id)
{
string Name = string.Empty;
//设定存储过程名
using (SqlCommand cmd = new SqlCommand("Proc_GetName", this.sqlCoon))
{
cmd.CommandType = System.Data.CommandType.StoredProcedure;
//输入参数
SqlParameter para = new SqlParameter();
para.ParameterName = "@Id";
para.SqlDbType = System.Data.SqlDbType.Int;
para.Value = Id;
//默认方向为Input
para.Direction = System.Data.ParameterDirection.Input;
cmd.Parameters.Add(para);
//输出参数
para = new SqlParameter();
para.ParameterName = "@Name";
para.DbType = System.Data.DbType.String;
para.Size = 10;
para.Direction = System.Data.ParameterDirection.Output;
cmd.Parameters.Add(para);
cmd.ExecuteNonQuery();
Name = (string)cmd.Parameters["@Name"].Value;
}
return Name;
}
11.数据库事务
事务是一组数据库操作,要么全部完成,要么全部不完成。
ACID:事务原子性(要么全完成,要么全不完成)、一致性(数据在整个事务中保持稳定)、隔离性(事务之间不会互相影响)、持久性(事务会保存和记录日志)
Commit()方法在所有数据库操作都完成才调用,为此,所有待定的改变都会持久化到数据库中。相反,Roolback()方法会在运行出现异常时进行调用,他会通知DMBS泛起所有待定的改变,保留原始数据。
/// <summary>
/// 事务
/// </summary>
public void DoTransaction(int Id, string Name)
{
string sqlRemove = string.Format("Delete from Table1 where Id = {0}", Id);
SqlCommand cmdRemove = new SqlCommand(sqlRemove, this.sqlCoon);
string sqlInsert = string.Format("Insert into Table1 values({0},'{1}')", Id, Name);
SqlCommand cmdInsert = new SqlCommand(sqlInsert, this.sqlCoon);
SqlTransaction tx = null;
try
{
tx = sqlCoon.BeginTransaction(); //从连接对象获得
//将命令加入到事务
cmdInsert.Transaction = tx;
cmdRemove.Transaction = tx;
//执行命令
cmdInsert.ExecuteNonQuery();
cmdRemove.ExecuteNonQuery();
tx.Commit();
}
catch (Exception ex)
{
tx.Rollback(); //有任何错误,回滚。
}
}