简介: Ado.Net是一种数据访问技术,访问的数据源可以是数据库(sqlserver、Oracle、mysql等),也可以是文本、XML或者EXCEL等.
Ado.Net的组成:
1.DataSet :非连接的核心组件,独立于任何数据源,存在于内存中,可以看成是内存中的数据库.(可以将数据源中的数据存到DataSet后断开与数据源的连接,然后对DataSet进行各种数据操作)
2.DataProvider(数据提供程序):
SQLServer数据提供程序 需引入System.Data.SqlClient
Oracle数据提供程序 需引入System.Data.OracleClient
OLEDB数据提供程序 需引入System.Data.Oledb
想了解通过oledb数据提供程序访问Excel数据源,请点我
ODBC数据提供程序 需引入System.Data.odbc
每一种数据提供程序都包含以下对象:
Connection: 提供与数据源的连接
Command: 执行命令的对象
DataReader:从数据源中提供快速的只读的数据流
DataAdpapter:是DataSet与数据源的桥梁,可以将数据源中的数据存到DataSet中,也可以将DataSet中的数据更新到数据源.
Parameter:表示Command对象的参数
......
Ado.Net访问数据源的步骤:
创建连接->打开连接->创建命令->执行命令->关闭连接
-------------------------------------------华丽的分割线----------------------------------------------------------
接下来以SQLServer数据提供程序为例来介绍其所包含的对象
1.SqlConnection
SqlConnection:建立与SQL Server数据库的连接.
SqlConnection对象常用的属性:
ConnectionString: 用于设置或获取连接字符串
DataBase:用于获取连接的数据库的名称
DataSource:用于获取数据库所在服务器
State:获取连接的状态()
ConnectionTimeout:等待连接开启的时间
SqlConnection对象常用的方法:
Open()://打开连接
Close():关闭连接
Dispose():释放连接
CreateCommand():创建一个与SqlConnnection对象相关联的SqlCommand对象.
//Close()和Dispose()的区别:Close关闭连接后该连接还可以再次打开;Dispose()关闭连接后,连接字符串会被重置为"",所以该连接也就不能再次打开了.
//获取连接字符串
string connstr = ConfigurationManager.ConnectionStrings["sws"].ConnectionString;
SqlConnection conn = null;
//使用using进行对象的释放,该对象必须实现了IDisposable接口(里面有一个Dispose()方法)
using (conn = new SqlConnection(connstr))
{
Console.WriteLine(conn.State);//State是Close
conn.Open();
}
Console.WriteLine(conn.State);//State是Close
conn.Open(); //conn连接打不开,会报"ConnectionString未初始化的错误",说明关闭连接时是用的Dispose()方法
题外话:
1.ConnectionString是什么?是一组被格式化的键值对,提供连接数据库时所需的信息.
SQL Server身份验证时连接字符串:--安全连接
Data Source=10.56.20.14;Initial Catalog=NewSWS_Test;User ID=MyUserID;Password=MyPassword
Windows身份验证时连接字符串:--信任连接
Server=./local;Database=NewSWS_Test;Integrated Security=SSPI/TRUE
或者 :
Server=./local;Database=NewSWS_Test;Trusted_Connection=true
2.我们可以通过SqlConnectionStringBuilder类来生成连接字符串,比如:
SqlConnectionStringBuilder conStrBuid = new SqlConnectionStringBuilder();
conStrBuid.DataSource = "10.56.20.14";
conStrBuid.DataBase= "NewSWS_Test";
conStrBuid.UserID = "MyUserID";
conStrBuid.Password = "MyPassword";
conStrBuid.Pooling = false;//默认连接池是开启的
conStrBuid.MaxPoolSize = 20;
string constr = conStrBuid.ConnectionString;
还可以根据这个类里面包含哪些属性来了解连接字符串可以做哪些键值对设置.
3.连接字符串的配置和获取(该配置和获取的环境是Web .Net Framework 4.7.2)
需要在web.config文件里面进行配置,如下:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
<!--配置连接字符串的时候可以在connectionString节点里配置也可以在appSettings里面配置,但是推荐在connectionStrings节点里配置,有关整个程序的配置才会在appSettings进行配置-->
<connectionStrings>
<add name="con1" connectionString="Data Source=10.56.20.14;Initial Catalog=NewSWS_Test;User ID=MyUserID;Password=MyPassword" providerName="Syetem.Data.SqlClient"/>
</connectionStrings>
<appSettings>
<add key="con1" value="Data Source=10.56.20.14;Initial Catalog=NewSWS_Test;User ID=MyUserID;Password=MyPassword"/>
</appSettings>
</configuration>
获取配置的连接字符串,如下:
//使用类ConfigurationManager需要引入Sytem.Configuration
//获取配置在connectionStrings节点里的连接字符串
string con1 = ConfigurationManager.ConnectionStrings["sws"].ConnectionString;
//获取配置在appSettings节点里的连接字符串
string con2 = ConfigurationManager.AppSettings["con1"];
4.连接池
4.1连接池是什么?
连接池是一个容器,里面存放了一定数量的与数据库服务器的物理连接.当我们需要连接数据库的时候就可以直接从连接池里面取出一条空闲的连接,而不是创建一个新的连接.这样就避免了因频繁创建和释放连接而造成的大量性能开销.
4.2连接池的区分:同一时刻同一应用程序域可以有多个不同类型的连接池,不同的连接池可以由windows标识、进程、应用程序域、连接字符串共同组成的签名来标识区分。对于同一应用程序域来说不同的程序池是由连接字符串来标识区分的。如果连接字符串有一点不一样,比如说a连接字符串与b连接字符串一样,只是比b多了一个空格,那么就会根据这两个连接字符串生成两个不同的连接池
4.3连接池如何分配连接?根据连接请求的类型找到相应的程序池,尽力分配一条空闲的连接,如果没有空闲的连接则在程序池创建一个新的连接进行分配,如果程序池已经达到了最大的连接数,连接请求会一直等待只到有空闲的连接.
4.4连接的回收:在连接使用完之后要及时的释放,我们一般使用SqlConnection对象的Close()和Dispose()方法来释放连接,释放后的连接会成为连接池中的一条空闲连接.另外提一嘴连接池管理器会自动移除无效的连接.
//连接一定要做到最晚打开最早关闭,如果提前打开连接而不执行命令会白白浪费连接资源.
//如果不及時释放连接,在连接达到连接池最大连接数量的时如果再开启一个连接就会报错:
string connstr = "Data Source=10.56.20.14;Initial Catalog=NewSWS_Test;User ID=MyUserID;Password=MyPassword;Max Pool Size=5";
for(int i = 0; i < 10; i++)
{
SqlConnection conn = new SqlConnection(connstr);
conn.Open();
}
4.5连接池的使用:Ado.Net是默认启用连接池的.
Pooling:设置连接池是否启用,
Max Pool Size=10:设置最大连接数量
Min Pool Size=5:设置最小连接数量(在收到第一个创建连接的请求时会自动创建5个连接,其中四个放在程序池闲置,一个提供给连接请求使用)
2. SqlCommand:
SqlCommand:对SQLServer数据库执行一个T-SQL语句或者存储过程
2.1SqlCommand对象常用的属性:
Connection:获取或设置Sqlcommand的对象使用的Sqlconnection对象
CommandText:获取或设置要执行的T-SQL语句或存储过程名
CommandType:
CommandType.Text:要执行的是一个SQL语句(默认)
CommandType.StoredProcedure:要执行的是存储过程
Parameters:Sqlcommand对象的命令参数集合(默认为null)
Transaction:获取或设置要在其中执行的事务
2.2 SqlCommand对象的创建:
一般是采用前三种创建方式:
//获取Web.config配置文件里面的字符串
string connstr = ConfigurationManager.ConnectionStrings["sws"].ConnectionString;
SqlConnection conn = new SqlConnection(connstr);
//第一种创建Sqlcommand对象的方式:
SqlCommand comm1 = new SqlCommand();
comm1.Connection = conn;
//comm1.CommandType=CommandType.StoredProcedure; //如果执行的命令是存储过程时,需要指定CommandType(默认是CommandType.Text)
comm1.CommandText = "select * from UsyUser"; //如果是CommandType.StoredProcedured,CommandText设置的是存储过程的名字
//第二种创建Sqlcommand对象的方式:
SqlCommand comm2 = new SqlCommand("select * from UsyUser");
comm2.Connection = conn;
//第三种创建Sqlcommand对象的方式:
SqlCommand comm3 = new SqlCommand("select * from UsyUser",conn);
//第四种创建Sqlcommand对象的方式:
SqlCommand comm4 = conn.CreateCommand();
comm4.CommandText = "select * from UsyUser";
2.1 SqlCommand对象常用的方法:
int ExecuteNonQuery():执行T-SQL或者存储过程并返回受影响的行数.用于执行增删改命令
object ExecuteScalar():返回查询结果集中第一行第一列的值,忽略其他的行与列.可以用于执行返回统计数据,比如count(*)等;也可用于返回插入数据后自动生成的标识列的值,比如@@identity,如果没有值返回null.
SqlDataReader ExecuteReader():返回的是DataReader,如上,DataReader用于从数据源中提供一个快速(读取数据的效率是比较高的)只读的数据流,相当于游标,只能前进读取,不能后退.在读取时连接必须处于Open状态,否者是读取不到数据的.
建议:DataReader适用于读取的数据量比较小的情况,因为读取的数据量比较大时会长时间占用连接浪费连接资源.如果读取的数据量比较大还是使用DataSet比较划算.
执行SqlDataReader()方法示例:
//获取Web.config配置文件里面的字符串
string connstr = ConfigurationManager.ConnectionStrings["sws"].ConnectionString;
SqlConnection conn = new SqlConnection(connstr);
SqlCommand comm3 = new SqlCommand("select * from UsyUser where UserNO='F2847958'", conn);
SqlDataReader dr = null;
try
{
conn.Open(); //conn要严格遵守最晚打开最早关闭的原则.
dr = comm3.ExecuteReader();
while (dr.Read())//推进到下一笔数据
{
string siteCode = dr["SiteCode"].ToString();
string userName = dr["UserName"].ToString();
}
}
catch(Exception ex)
{
throw new Exception("执行查询出错:" + ex.Message);
}
finally
{
dr.Close(); //DataReader对象使用完毕,不要忘记将其释放
conn.Close(); //注意当conn关闭后dr也会被关闭,而dr关闭,conn不会被关闭.所以上面的dr.Close可以不写
}
3. SqlParameter
SqlParameter:表示SqlCommand对象的参数,或与DataSet中列的映射.使用SqlParameter即可解決SQL注入问题,又可转义单引号(比如学校名字具有单引号'会导致'Tom's School'报异常)
3.1 SqlParameter对象常用的属性:
ParameterName:参数的名称
Value:参数的值
SqlDbType:获取或设置参数在数据库中是什么类型
Direction:获取或设置参数的类型:输入(默认)、输出、输入输出、返回值.输入参数用于参数化的T-SQL语句或一般的存储过程;输出、输入输出、返回值参数用于存储过程.
Size:获取或设置参数的最大大小,以字节为单位,根据Value判断要设置的大小
3.2 创建SqlParameter对象:
//第一种
SqlParameter para1 = new SqlParameter();
para1.ParameterName = "@UserNo";//不带@符号可以吗?
para1.Value = "F2847958";
para1.SqlDbType = SqlDbType.VarChar;
para1.Size = 20;//获取或设置
//第二种
SqlParameter para2 = new SqlParameter("@UserNo", "F2847958");//这种最常用
//第n种......
3.3 SqlCommand对象添加参数:
//获取Web.config配置文件里面的字符串
string connstr = ConfigurationManager.ConnectionStrings["sws"].ConnectionString;
SqlConnection conn = new SqlConnection(connstr);
SqlCommand comm = new SqlCommand("select * from UsyUser where SiteCode=@siteCode AND BUCode=@buCode AND DelFlag=@delFlag", conn);
//添加单个参数时,有如下添加方式
//第一种添加方式
SqlParameter para1 = new SqlParameter("@siteCode", "LH");
comm.Parameters.Add(para1);
//第二种添加方式(这种添加方式已经Obsolete,不推荐使用)
comm.Parameters.Add("@buCode", "WLBG");
//第三种添加方式,推荐使用这种方式
comm.Parameters.AddWithValue("@delFlag","0");
//获取Web.config配置文件里面的字符串
string connstr = ConfigurationManager.ConnectionStrings["sws"].ConnectionString;
SqlConnection conn = new SqlConnection(connstr);
SqlCommand comm = new SqlCommand("select * from UsyUser where SiteCode=@siteCode AND BUCode=@buCode AND DelFlag=@delFlag", conn);
//SqlCommand对象一次添加多个参数时的方式
SqlParameter[] paras = {
new SqlParameter("@siteCode","LH"),
new SqlParameter("@buCode","WLBG"),
new SqlParameter("@delFlag","0")
};
comm.Parameters.AddRange(paras);
值得注意的是:
当使用字符串拼接参数时,如下sql:
string sql = "select * from UsyUser where SiteCode='"+siteCode+"' ;
当siteCode="L'F"时会出现错误,
当siteCode="'' or 1=1--'"时就被SQL注入了
当使用SqlParameter添加参数时,不管siteCode="L'F"还是siteCode="'' or 1=1--'",执行时都会被看成是@siteCode的值,这样就实现了转义'和避免SQL注入的问题.
new SqlParameter("@siteCode",siteCode)
3.4 输出参数的使用:
--第一步:先创建一个简单的存储过程
create proc sp_GetUserName
@userNo varchar(10),
@userName nvarchar(10) output --@userName就是输出参数
as
begin
select @userName=UserName from usyUser where UserNO=@userNo
end
//第二步代码实例展示
string connstr = ConfigurationManager.ConnectionStrings["sws"].ConnectionString;
SqlConnection conn = new SqlConnection(connstr);
SqlCommand comm = new SqlCommand("sp_GetUserName", conn);
comm.CommandType = CommandType.StoredProcedure;
SqlParameter paraUserNo = new SqlParameter("@userNo", "F2847958");
SqlParameter paraUserName = new SqlParameter("@userName",SqlDbType.NVarChar,20);//由于@userName是输出参数,所以这里不需要赋值
paraUserName.Direction = ParameterDirection.Output; //这里不要忘记设置输出参数的Direction为Output
comm.Parameters.Add(paraUserNo);
comm.Parameters.Add(paraUserName);
try
{
conn.Open();
comm.ExecuteNonQuery();
}
catch (Exception ex)
{
throw new Exception("执行查询出错" + ex.Message);
}
finally
{
string userName = paraUserName.Value.ToString();//获取到输出参数的值
conn.Close();
}
3.4 输入输出参数的使用:
--第一步创建一个简单的存储过程
create proc sp_GetUserNo
@userNo varchar(10) output --也需要使用output进行标识
as
begin
select @userNo=@userNo+UserName from usyUser where UserNO=@userNo
end
//第二步代码实例展示
string connstr = ConfigurationManager.ConnectionStrings["sws"].ConnectionString;
SqlConnection conn = new SqlConnection(connstr);
SqlCommand comm = new SqlCommand("sp_GetUserNo", conn);
comm.CommandType = CommandType.StoredProcedure;
SqlParameter paraUserNo = new SqlParameter("@userNo", "F2847958");
paraUserNo.Direction = ParameterDirection.InputOutput; //这里不要忘记设置输入输出参数的Direction为Output
comm.Parameters.Add(paraUserNo);
try
{
conn.Open();
comm.ExecuteNonQuery();
}
catch (Exception ex)
{
throw new Exception("执行查询出错" + ex.Message);
}
finally
{
string userName = paraUserNo.Value.ToString();//获取到输出参数的值
conn.Close();
}
3.5 返回参数的使用:
--第一步创建一个简单的存储过程
create proc sp_GetUserGradeLevel
@userNo varchar(10)
as
begin
declare @GradeLevel int
select @GradeLevel=GradeLevel from usyUser where UserNO=@userNo
return @GradeLevel --返回参数只能返回int类型的值
end
//第二步代码实例展示
string connstr = ConfigurationManager.ConnectionStrings["sws"].ConnectionString;
SqlConnection conn = new SqlConnection(connstr);
SqlCommand comm = new SqlCommand("sp_GetUserGradeLevel", conn);
comm.CommandType = CommandType.StoredProcedure;
SqlParameter paraUserNo = new SqlParameter("@userNo", "F2847958");
SqlParameter paraReturnValue = new SqlParameter("@reValue", SqlDbType.Int);//因为是返回参数,所以不需要输入值
paraReturnValue.Direction = ParameterDirection.ReturnValue;//这里要给返回参数的Direction设置成ParameterDirection.ReturnValue
comm.Parameters.Add(paraUserNo);
comm.Parameters.Add(paraReturnValue);
try
{
conn.Open();
comm.ExecuteNonQuery();
}
catch (Exception ex)
{
throw new Exception("执行查询出错" + ex.Message);
}
finally
{
int age = (int)paraReturnValue.Value;//获取到输出参数的值
conn.Close();
}
4. SqlDataAdapter 与 DataSet
//废话不多说,直接看代码
string connstr = ConfigurationManager.ConnectionStrings["sws"].ConnectionString;
SqlConnection conn = new SqlConnection(connstr);
SqlCommand comm = new SqlCommand("select * from UsyUser", conn);
SqlDataAdapter adapt = new SqlDataAdapter(comm);
DataTable dt = new DataTable();
DataSet ds = new DataSet();
try
{
conn.Open();
adapt.Fill(dt);
adapt.Fill(ds);
}
catch (Exception ex)
{
throw new Exception("执行查询出错" + ex.Message);
}
finally
{
conn.Close();
}
朋友看到这里你对Ado.Net就已经比较全面了解了.就还差两个知识点,一个是事务,另一个是如何将DataSet中的数据同步到数据源,这两个问题就留给朋友你来自行解决了