1.数据库工厂 位于System.Data.Common
DbCommand:所有命令类的抽象类 -> IDbCommand
DbConnection:所有连接类的抽象基类 ->IDbConnection
DbDataAdapter:所有数据适配器类的抽象类 ->IDbDataAdapter
DbDataReader:所有数据读取器类的抽象类->IDbDataReader
DbParameter:所有参数的抽象基类->IDbParameter
DbTranscation:所有事务类的抽象基类 ->IDbTranscation
每个微软提供的数据提供程序都有一个继承自System.Data.Common DbProviderFactory的类。这个基类定义了一些方法来获取某数据提供程序的数据对象。
public abstract class DbProviderFactroy{
...
public virtual DbCommand CreateCommand();
public virtual DbCommandBuilder CreateCommandBuilder();
public virtual DbConnection CreateConnection();
public virtual DbConnectionStringBuilder CreateConnectionStringBuilder();
public virtural DbDataAdapter CreateDataAdapter();
public virtural DbDataSourceEnumerator CreateDataSourceEnumerator()
public virtual DbParameter CreateParameter();
}
例如:
DbProviderFactory sqlFactory=DbProviderFactories.GetFactory("System.Data.SqlClient");//获取Sql数据提供程序工厂
这和JAVA类似:Java.Classfor("MySql"),当然,上面这些实现接口的抽象类让我们想起了当初Java中大量的XXXAdapter抽象了来实现接口,避免在泛华接口时大量实现不必要实现的方法而劳费精神。
例如:
static void Main(string[] args)
{
string dp = ConfigurationManager.AppSettings["provider"];
string cnStr = ConfigurationManager.AppSettings["connStr"];
//获取SQL数据提供程序工厂
DbProviderFactory sqlFactory = DbProviderFactories.GetFactory(dp);
DbConnection conn = sqlFactory.CreateConnection();
conn.ConnectionString =cnStr;
try
{
conn.Open();
Console.WriteLine("DBType:{0} Connected:{1}", conn.GetType().Name, "Successful!");
//得到命令对象
DbCommand cmd = sqlFactory.CreateCommand();
Console.WriteLine("Your command object is a:{0}",cmd.GetType().Name);
cmd.Connection = conn;
cmd.CommandText = "select * from inventory";
//从数据表中读取数据
using (DbDataReader dr = cmd.ExecuteReader())
{
Console.WriteLine("Your data reader object is a:{0}",dr.GetType().Name);
Console.WriteLine("
*********** current Inventory ***************");
while (dr.Read())
{
Console.WriteLine("->Car #{0} is a {1}",dr["CarId"],dr["Make"].ToString());
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadLine();
}
数据提供DataProvider程序工厂模型的潜在缺陷:
尽管这个模型很强,但是你需要知道,代码库其实只能通过抽象基类的成员来使用所有提供程序通用的一些类型和方法。因此在写代码库的时候,你会被局限于System.Data.Common命名空间下的DbConnection、DbCommand等其他类型公开的成员。这样,你就会发现,这种“泛化的”方式使得我们不能直接访问特定DBMS的漂亮功能。如果我们必须调用基础提供程序(比如SqlConnection)的特殊成员,那么可以通过显式强制类型转换就能实现。
例如:using(DbConnection cn=df.CreateConnection()){
if (conn is SqlConnection)
{
Console.WriteLine("The Database Version is {0}",((SqlConnection)conn).ServerVersion);
}
}
DBConnection类型的成员
BeginTransaction() 用来开始数据库事务
ChangeDatabase() 为打开的连接更改当前数据库
ConnectionTimeout 这个只读属性建立连接时终止尝试并生成错误之前所等待的时间(默认15秒)如果想修改这个值,请在连接字符串中加入Connect Timeout片段(比如 Connect Timeout=30)
Database 获取连接对象的数据库名
DataSource 获取连接对象的数据库服务器名
GetSchema() 返回一个包含数据源结构信息的DataTable对象
State 这个只读属性获取当前连接状态,表示为ConnectionState枚举形式。
我们知道,DbConnection类型的这些属性实际上是只读的,只有我们想在运行时得到连接的一些特征才会去用他们。
如果需要修改这些默认设置的话,必须改变连接字符串本身。
SqlConnectionStringBuilder //通过数据库连接对象来配置数据库连接字符串。
public enum CommandType{
StoredProcedure,
TableDirect,
Text //默认值
}
DbCommand类型的成员
ConnectionTimeout 获取或设置在终止执行命令的尝试并生成错误之前的等待时间,默认30秒
Connection 获取或设置DbCommand 实例使用的DbConnection
Parameters 获取DbParameters对象的集合,用于参数化查询
Cancel() 取消执行命令
ExecuteReader() 执行SQL查询并返回数据提供程序对象DbDataReader对象,以只读向前的方式访问查询结果。
ExecuteNoQuery()提交Sql语句到数据库,不会有返回值(如插入、更新、删除或创建表)
ExecuteScalar()一个轻量级的ExecuteReader(),用于返回一个值得查询,比如记录总数。
Prepare() 在数据源上创建该命令的贮备好(或已编译)的版本,我们知道这样一个查询的执行速度会稍微快些(特别是你想多次执行相同查询的情况下)
数据读取器
DbDataReader->IDbDataReader (只读向前的数据流,并且一次返回一条记录) while(dr.Read()){}
当你需要快速获取大批数据并且不需要再内存中存储他们的时候,数据读取器就非常有用了。而DataSet读取数据的同事在内存中保存整个结果。但是,数据读取器对象会保持打开的连接,除非显式关闭会话。
通过执行命令对象的ExecuteReader()方法来获取数据读取器对象。数据读取器(DataReader)表示从数据库中读取的当前记录,它包含一个所引起方法(如[]语法),可以通过名称或0开始的整数来访问当前记录中的列。
使用数据读取器获取多个结果集
string sqlStr="select * from Inventory;select * from Customers";
获得了数据读取器对象后,就能通过NextResult()方法循环所有的结果集。需要知道的是,他会总是自动返回第一个结果集。
例如:
cmd.CommandText = "select * from Inventory;select * from Customer";
using (DbDataReader dr1 = cmd.ExecuteReader())
{
do {
Console.WriteLine("******* record ********");
for (int i = 0; i < dr1.FieldCount; i++)
{
Console.WriteLine("{0}={1}",dr1.GetName(1),dr1.GetValue(i).ToString());
}
Console.WriteLine();
}
while (dr1.NextResult());
}