简介
一种数据访问技术,应用程序可以连接到数据库,并以各种方式来操作其中的数据。一个COM组件库,.Net中访问数据,优先选择的数据访问接口。
ADO ActiveX Data Objects 早期开发人员用来访问数据库的组件。.Net Ado.Net逐步取代了ADO
它们之间的关系?
ADO.NET是ADO的升级版,严格上来,它们又是两种截然不同的方式。
技术上 ADO OLEDB接口 基于COM技术,
ADO.NET拥有自己的接口,基于.NET体系架构。
组成
System.Data.dll中,system.data命名空间,提供不同ado.net类
组成:
1、DataSet 非连接的核心组件。独立于任何数据源的数据访问,适合多种不同的数据源(excel等)
2、Data Provider(数据提供程序):用于连接数据库、执行命令、检索结果。
sql server数据提供程序 system.data.sqlclient命名空间
OLEDB的数据提供程序 system.data.oledb命名空间
odbc的数据提供程序 system.data.odbc命名空间
ORACLE数据提供程序 system.data.OracleClient命名空间
connection 提供与数据源的连接 sqlconnection
command 用于执行数据库命令的对象 sqlcommand
datareader 从数据源中提供快速的,只读的数据流 sqldatareader
DataAdapter 提供dataset对象与数据源的桥梁。Fill方法 update方法
sqlconnection介绍
ADO.NET访问数据的步骤
连接到数据库 打开连接 创建执行命令对象(创建命令) 执行命令 关闭连接
sqlconnection类 继承于 DbConnection 抽象基类,不能被实例化。提供与sqlserver数据库的连接。
vs2019无法引用system.data.sqlclient的解决办法
常用属性
connection state database datasource
state:Closed 已关闭状态 open 打开状态 connecting 正在连接 Executing 正在执行命令 Fetching 正在检索数据 Broken 连接中断
常用方法
open close dispose等
using System.Data.SqlClient;
using System.Configuration;
//1、创建连接
SqlConnection con = new SqlConnection();//实例化
con.ConnectionString = "server=.;database=my_database;uid=sa;pwd=123";//连接字符串
//con.Database = "";//要连接的数据库名称
//con.DataSource //数据源 本地话用local或者一个. 远程的话就是Ip,端口号
//con.State//连接的状态
//con.ConnectionTimeout//默认15s 连接失败,尝试连接到最终终止操作的时间
//con.ServerVersion//数据库版本
//2、打开连接
con.Open();//打开连接
//3、创建执行命令对象
con.CreateCommand();//创建一个与con关联的sqlconmmand对象
//4、执行命令
//5、关闭连接
con.Close();//关闭连接
con.Open();
con.Dispose();//释放连接
//差别:Close()后还可以再打开,连接字符串还有
//Dispose后,连接字符串没有,被清空,再打开要重新设置连接字符串
连接字符串
connectionstring
字符串,一组被格式化的键值对,数据源在哪里,数据库名,提供什么样的访问级别,其他相关信息。
格式:一组元素组成,一个元素——键值对,各个元素之间用“;”隔开。
sql server身份验证
Data Source 数据源
Initial Catalog 数据库名
User Id 账号
Password密码
windows身份验证
Data Source 数据源
Initial Catalog 数据库名
Intergrated Securitty=True/SSPI(或者写成Trusted_Connection=true)
SqlConnection con = new SqlConnection();
//sql server身份验证 安全连接
string ConStr = "Data Source=.;Initial Catalog = TestBase;User Id=sa;Password=123";
//或者写成 Data Source---server Initial Catalog---database User Id--uid Password---pwd
//windows身份验证 可信连接
string ConStr = "Data Source=.;Initial Catalog = TestBase;Intergrated Security=SSPI";
Oracle
Data Source User Id Password;
mysql
data source initial catalog user id password;
access
provider=microsoft.jet.oledb.4.0;data source=文件的绝对路径 User Id = admin;Password=1234;
构建连接字符串及其配置
1、构建:
1)手写
2)专门的类来构建连接字符串 DbConnectionStringBuilder 基类 SqlConnectionStringBuilder
SqlConnectionStringBuilder ConStrBuilder = new SqlConnectionStringBuilder();
ConStrBuilder.DataSource =".";
ConStrBuilder.UserID = "sa";
ConStrBuilder.InitialCatalog = "TestBase";
ConStrBuilder.Password = "123";
ConStrBuilder.Pooling = false;//禁用连接池
//ConStrBuilder.ConnectTimeout
//ConStrBuilder.MinPoolSize//最小连接数
//ConStrBuilder.MaxPoolSize
程序代码中写连接字符串,如果要修改,过后重新编译,灵活性很差,如何解决?——存储在配置文件
如何把连接字符串从配置文件中取出来?
2、配置文件中存储
配置到文件中 ConnectionString节点中 appSetting节点汇中
注意将配置文件中的文本字符串给删除,不然连接字符串会提示不能包含文本字符串。
//配置连接字符串
<connectionStrings>
<add name="ConStr"
connectionString="Server=.;database=TestBase;uid=sa;pwd=123"
providerName="system.data.sqlclient"/>
</connectionStrings>
//配置到appSetting
<appSettings>//一般用来配置与应用程序相关的信息
<add key="ConStr" value="Server=.;database=TestBase;uid=sa;pwd=123"/>
</appSettings>
//读取配置文件里的连接字符串
//首先右键引用system.configuration程序集
SqlConnection con = new SqlConnection();
string ConStr = ConfigurationManager.ConnectionStrings["ConStr"].ConnectionString;
//读取连接字符串
con.ConnectionString = ConStr;
//appSetting
SqlConnection con = new SqlConnection();
string ConStr = ConfigurationManager.AppSettings["ConStr"].ToString();
//读取连接字符串
con.ConnectionString = ConStr;
连接对象的创建及使用
异常处理:try{ }//异常放里面
catch(){ }//异常处理
finally{ }//可选的,释放用
SqlConnection con1 = null;
try
{
string connStr = ConfigurationManager.ConnectionStrings["ConStr"].ConnectionString;
//创建con连接第一种方式
//SqlConnection con = new SqlConnection();
//con.ConnectionString = connStr;
//2.创建con 推荐使用
con1 = new SqlConnection(connStr);
Console.WriteLine($"Data Source:{con1.DataSource}");
Console.WriteLine($"DataBase:{con1.Database}");
//关闭状态的版本号得不到,所以会出错
Console.WriteLine($"ServerVersion:{con1.ServerVersion}");
Console.WriteLine($"State:{con1.State}");
//打开连接,进行与数据库的交互,操作数据
//如果数据库不存在就无法打开
con1.Open();
Console.WriteLine($"连接对象打开之后:");
Console.WriteLine($"Data Source:{con1.DataSource}");
Console.WriteLine($"DataBase:{con1.Database}");
Console.WriteLine($"ServerVersion:{con1.ServerVersion}");
Console.WriteLine($"State:{con1.State}");
//执行命令
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);//处理异常
}
finally
{
con1.Close();//dispose()
}
using语句块 ——先try 再finally 没有catch处理异常 ——最后释放对象
using 引用命名空间
using 名别名 using Con = System.Configuration.ConfigurationManager;//放在最前面
//连接对象离开using区域后,状态变成closed
string ConStr = ConfigurationManager.ConnectionStrings["ConStr"].ConnectionString;
using (SqlConnection con1 = new SqlConnection(ConStr))
{
//使用using进行释放的对象,它必须继承于IDisposable接口
//f12查看sqlconnection——DbConnection——IDisposable
Console.WriteLine($"Data Source:{con1.DataSource}");
Console.WriteLine($"DataBase:{con1.Database}");
Console.WriteLine($"State:{con1.State}");
//打开连接,进行与数据库的交互,操作数据
//如果数据库不存在就无法打开
con1.Open();
Console.WriteLine($"连接对象打开之后:");
Console.WriteLine($"Data Source:{con1.DataSource}");
Console.WriteLine($"DataBase:{con1.Database}");
Console.WriteLine($"ServerVersion:{con1.ServerVersion}");
Console.WriteLine($"State:{con1.State}");
}
连接池的介绍
为什么使用连接池?
前面的连接是非常耗时耗力的一件事。经历几个阶段,建立物理通过,与服务器初次的握手,分析连接字符串,身份验证。重复利用已有的连接?——连接池
连接池是什么
优化, 容器:存放了一定数量的与数据库服务器的物理连接。
需要——容器里取出一条空闲的连接,而不是创建一条新的连接。
作用:减少了连接数据库的开销,从而提高了应用程序的性能
分类:类别区分,同一时刻统一饮用程序域可以有多个不同类型的连接池。
什么来标识区分——金城、应用程序域、连接字符串、windows标识共同组成的签名来标识区分。
对同一程序域来说,由连接字符串来区分。 打开一条连接,如果这条连接的类型签名与现有的连接不匹 配,就会创建一个新的连接池,反之则不会创建,它们会共用一个连接池。
如何分配
根据连接请求的类型,找到与他相匹配的连接池,尽力的分配一条空闲的连接。
有空闲的连接,返回这条连接
已用完,创建一个新连接添加到连接池中
已达到了最大连接数,等待,直到有空闲的连接可用
移除无效连接
不能正确的连接到数据库副武器的连接 连接池存储的与数据库服务器的链接数量是有限的。
无效链接,我么应当移除。浪费连接控件 连接池管理器会处理无效连接的移除问题。
回收连接
释放使用完的连接? 应当及时关闭或释放,,con对象的close dispose 连接回到连接池。
连接池的使用
ADO.NET默认是启用连接池的。
连接字符串是可以控制连接池的行为的。
1、测试连接池的存在
string constr = "server=.;database=my_database;uid=sa;pwd=123;Max Pool Size=5";
for (int i = 0; i < 10; i++)
{
SqlConnection con = new SqlConnection(constr);
con.Open();
Console.WriteLine($"第{i + 1}个连接已打开");
}
//1、证明:ADO.NET是默认启用连接池的。
2、三个属性
Max Pool Size:最大连接数 默认100
Min Pool Size:最大连接数 默认0
Pooling:是否启用连接池 true
string constr = "server=.;database=my_database;uid=sa;pwd=123;Max Pool Size=5;Pooling=false";
for (int i = 0; i < 10; i++)
{
SqlConnection con = new SqlConnection(constr);
con.Open();
Console.WriteLine($"第{i + 1}个连接已打开");
}
//2、pooling=false禁止启用连接池,Max Pool Size=5是无效的
3、测试连接启用与否的耗时
Stopwatch sw = new Stopwatch();
sw.Start();
string constr = "server=.;database=my_database;uid=sa;pwd=123;Pooling=false";
for (int i = 0; i < 100; i++)
{
SqlConnection con = new SqlConnection(constr);
con.Open();
//Console.WriteLine($"第{i + 1}个连接已打开");
con.Close();
}
sw.Stop();
Console.WriteLine($"不启用连接池,耗时:{sw.ElapsedMilliseconds}ms!");
Stopwatch sw1 = new Stopwatch();
sw1.Start();
string constr1 = "server=.;database=my_database;uid=sa;pwd=123";
for (int i = 0; i < 100; i++)
{
SqlConnection con = new SqlConnection(constr);
con.Open();
//Console.WriteLine($"第{i + 1}个连接已打开");
con.Close();
}
sw1.Stop();
Console.WriteLine($"启用连接池,耗时:{sw1.ElapsedMilliseconds}ms!");
////3、测试启用与不启用连接池,性能差,连接池耗能很少
4、连接池类别区分测试(连接字符串来区分)
string constr1 = "server=.;database=my_database;uid=sa;pwd=123;max pool size=5";
string constr2 = "server=.;database=my_database; uid=sa;pwd=123;max pool size=5";
//constr2这个连接字符串多一个空格
string constr3 = "server=.;database=my_database;uid=sa;pwd=123;max pool size=5";
//4、会产生几个连接池
for (int i = 0; i < 5; i++)
{
SqlConnection con1 = new SqlConnection(constr1);
con1.Open();
Console.WriteLine($"con1第{i + 1}个连接已打开!");
SqlConnection con2 = new SqlConnection(constr2);
con2.Open();
Console.WriteLine($"con2第{i + 1}个连接已打开!");
SqlConnection con3 = new SqlConnection(constr3);
con3.Open();
Console.WriteLine($"con3第{i + 1}个连接已打开!");
}
//constr1与constr3一样的,所以它们共用一个连接池,constr2会单独创建一个连接池——2个连接池
sqlcommand介绍及创建
sqlcommand 对sqlserver数据库执行的一个T-SQL语句或存储过程。
sqlcommand对象:ADO.NET中执行数据库命令的对象。
重要属性:
connection:sqlcommand对象要使用的sqlconnection
commandtext:获取或设置要执行的T-SQL语句或存储过程名
commandtype:1、commandtype.text—执行的是一个sql语句
2、commandtype.StoredProcedure—执行的是一个存储过程
带参数的查询必须设置这个值
Parameters:sqlcommand对象的命令参数集合 默认为空集合
Transaction:获取或设置要在其中执行的事务
string constr = ConfigurationManager.ConnectionStrings["ConStr"].ConnectionString;
try
{
using (SqlConnection con = new SqlConnection(constr))
{
con.Open();
//1、
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
string sql = "select * from student";
cmd.CommandText = sql;
//cmd.CommandType = CommandType.Text;//如果执行的是一个sql语句,没有必要的
//cmd.CommandType = CommandType.StoredProcedure;//如果是存储过程必须设置
//cmd.Parameters.Add
//add和addrange,add是单个参数添加,addrange是参数数组的添加
//2、
SqlCommand cmd1 = new SqlCommand(sql);
cmd1.Connection = con;
//3、sql语句 连接对象 推荐的
SqlCommand cmd2 = new SqlCommand(sql, con);
//4、Connection对象
SqlCommand cmd3 = con.CreateCommand();
cmd3.CommandText = sql;
//5、
string delsql = "delete from student where sex='男'";
SqlCommand cmd4 = new SqlCommand(delsql, con, null);
}
}
catch (Exception)
{
throw;
}
finally
{
}
ExecuteNonQuery
command执行方法
cmd.ExecuteNonQuery();
cmd.ExecuteScalar();
cmd.ExecuteReader();
ExecuteNonQuery介绍
//1.执行T-SQL语句或存储过程并返回受影响的行数
//命令类型:插入、更新、删除——DML
ExecuteNonQuery使用
string constr = ConfigurationManager.ConnectionStrings["ConStr"].ConnectionString;
int count = 0;
using (SqlConnection con = new SqlConnection(constr))
{
string uSname = "李良";
string usex = "男";
DateTime ubirth = DateTime.Now;
int uclassno = 144;
//创建命令 T-SQL 存储过程
//拼接式sql 致命弱点:容易被注入
string sql = "insert into student (Sname,sex,birth,classno) values('" + uSname + "','" + usex + "','"+ubirth+"'," + uclassno + ")";
//创建执行命令的对象sqlcommand
SqlCommand cmd = new SqlCommand(sql, con);
//执行命令
//1、执行T-SQL语句或存储过程并返回受影响的行数
//命令类型:增删改——DML
//共有的条件:con状态必须是open
//连接使用原则:最晚打开,最早关闭
con.Open();
count = cmd.ExecuteNonQuery();
//con.Close();//因为是using所以可以不写
}
if (count > 0)
{
Console.WriteLine("信息添加成功!");
}
Console.ReadKey();
ExecuteScalar方法
1、介绍 执行查询语句或存储过程,返回查询结果集中的第一行第一列的值,忽略其他行或列。
cmd.executescalar()查询DQL 返回的是一个值object
适用:作查询,返回一个值 记录数 数据运算而出的结果
有时,插入数据后,想返回自动生成的标识列的值,我们也可以用这个方法
2、使用
string constr = ConfigurationManager.ConnectionStrings["ConStr"].ConnectionString;
object o = null;
using (SqlConnection con = new SqlConnection(constr))
{
//string sql = "select * from 查询结果$";
string sql = "insert into student(Sname,sex,classno) values('李雷','男','123');select @@identity";
SqlCommand cmd = new SqlCommand(sql,con);
con.Open();
o = cmd.ExecuteScalar();
}
if (o != null)
{
Console.WriteLine("返回值:" + o.ToString());
}
Console.ReadKey();
ExecuteReader方法
1、介绍
查询返回一个对象:SqlDataReader
SqlDataReader 数据流 实时读取 游标 像指针一样 固定——不灵活:只进不出,只能前进,不能后退
只读
适用:读取数据
2、使用
string constr = ConfigurationManager.ConnectionStrings["ConStr"].ConnectionString;
SqlDataReader dr = null;
using (SqlConnection con = new SqlConnection(constr))
{
string sql = "select * from student";
SqlCommand cmd = new SqlCommand(sql,con);
con.Open();
dr = cmd.ExecuteReader();
//dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
//可以用这个参数提前关闭连接
//dr读取数据过程中,要即时保存,因为读一条丢一条
while (dr.Read())//是否可以前进到下一条记录
{
string sname = dr["Sname"].ToString();
string sex = dr["sex"].ToString();
string birth = dr["birth"].ToString();
string classno = dr["classno"].ToString();
Console.WriteLine($"{sname},{sex},{birth},{classno}");
}
}
Console.ReadKey();
SqlParameter
定义 表示sqlcommand对象的参数,或与DataSet中列的映射。
常用属性
DbType 参数的SqlDbType(数据类型 数据库的类型而言)
Direction 参数的类型:输入 输出 输入输出、返回值参数
ParameterName 参数的名称
Size 参数存储数据的最大大小 字节为单位
Value 参数的值
SqlValue 作为SQL类型的参数的值
构造方法
using System.Data.SqlClient;
using System.Data;
//参数的构造方法
//1、参数
SqlParameter pra1 = new SqlParameter();
pra1.ParameterName = "@userName";
pra1.SqlDbType = SqlDbType.VarChar;
pra1.Value = "admin";
pra1.Size = 20;
//2、参数名,参数值
SqlParameter pra2 =new SqlParameter("@Age",24);
//3、参数名 SqlDbType
SqlParameter pra3 = new SqlParameter("@DeptId",SqlDbType.Int);
pra3.Size = 4;//4个字节
pra3.Value = 3;
//4、参数名,类型,大小
SqlParameter pra4 = new SqlParameter("@UserPwd",SqlDbType.VarChar,50);
pra4.Value = "123456";
//5、参数名,类型,大小,源列名(对应DataTable中的列名)
SqlParameter pra5 = new SqlParameter("@UserName",SqlDbType.VarChar,20,"UserName");
sqlcommand添加参数
参数的作用
不带任何条件,不是通过参数传递,而是拼接SQL语句,生成SQL,具体的值
拼接SQL:容易被SQL注入
防止SQL注入 转义
Command添加参数的方法
cmd.Parameters.Add()
cmd.parameters.AddWithValue()
cmd.Parameters.AddRange()
string constr = ConfigurationManager.ConnectionStrings["ConStr"].ConnectionString;
using (SqlConnection con = new SqlConnection(constr))
{
int classno = int.Parse(Console.ReadLine());
string sql = "select ID,Sname,sex,birth,classno from student where Sname=@sname";
SqlCommand cmd = new SqlCommand(sql, con);
//SQL注入?
//select * from student where Sname = '李雷' or '1' = '1' and Password = '1' or '1' = '1'
//存在单引号怎么办?
//select * from student where Sname='李'雷'
//参数 解决单引号问题和SQL注入问题
//参数化SQL语句或一般存储过程里使用的是输入参数
/*cmd.Parameters.Add(new SqlParameter("@sname", "李'雷"));
SqlParameter paraName = new SqlParameter("sname","李'雷");
cmd.Parameters.Add(paraName);添加单个参数*/
//cmd.Parameters.Add("@sname", "李'雷");//过时了
cmd.Parameters.AddWithValue("@sname", "李'雷");//单个参数的添加,推荐使用这种
//SqlParameter pra = cmd.Parameters.Add("@sname", SqlDbType.VarChar,20);
//pra.Value = "李'雷";
//添加多个参数时使用
//SqlParameter[] pra1 =
//{
// new SqlParameter("@sname","李'雷")
//};
//cmd.Parameters.AddRange(pra1);
con.Open();
object o = cmd.ExecuteScalar();
con.Close();
Console.WriteLine(o.ToString());
}
Console.ReadKey();
参数的使用
输入参数
参数化SQL语句或存储过程,默认使用的参数——输入参数
//para1.Direction = ParameterDirection.Input;//默认为输入参数
以下三种:用在存储过程里
输出参数
sql中output标识 程序中是可以接收到存储过程里需要返回的值 而不用使用return语句
Direction:Output
create proc GetDeptName
@DeptId int,
@DeptName nvarchar(50) output --输出参数
as
begin
select @DeptName=DeptName from DeptInfos
where DeptId=@DeptId
end
SqlCommand cmd = new SqlCommand("GetDeptName", con);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter paraId = new SqlParameter("@DeptId",2);
cmd.Parameters.Add(paraId);
//输出参数 是不传入值,它只是输出
SqlParameter paraname = new SqlParameter("@DeptName", SqlDbType.NVarChar,50);
paraname.Direction = ParameterDirection.Output;
cmd.Parameters.Add(paraname);
con.Open();
cmd.ExecuteScalar();
con.Close();
Console.WriteLine(paraname.Value.ToString());
输出输出参数
sql中output进行标识 他需要传入值,也输出值 不用return
value
Direction:InputOutput
create proc GetDeptNameNew
@DeptName nvarchar(50) output
as
begin
select @DeptName=DeptName from DeptInfos
where DeptName like '%'+@DeptName+'%'
end
SqlCommand cmd = new SqlCommand("GetDeptNameNew", con);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter paraname = new SqlParameter("@DeptName", SqlDbType.NVarChar,50);
paraname.Value = "发";
paraname.Direction = ParameterDirection.InputOutput;
cmd.Parameters.Add(paraname);
con.Open();
cmd.ExecuteScalar();
con.Close();
Console.WriteLine(paraname.Value.ToString());
返回值参数
他不出现在存储过程中 只可以返回的int类型 return返回值 如果字符串类型,那么就会报错
Direction:ReturnValue
--return不能返回int类型以外的值
create proc GetUserAge
@UserId int
as
begin
declare @age int
select @age=Age from UserInfos
where UserId=@UserId
return @age--只能是int类型
end
SqlCommand cmd = new SqlCommand("GerUserAge", con);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter[] paras =
{
new SqlParameter("@UserId",31),
new SqlParameter("@reValue",SqlDbType.Int,4)
};
paras[1].Direction = ParameterDirection.ReturnValue;//返回值参数
cmd.Parameters.AddRange(paras);
con.Open();
cmd.ExecuteScalar();
con.Close();
Console.WriteLine(paras[1].Value.ToString());
SqlDataReader
介绍
定义 提供一种从sqlserver数据库中读取只进的行流的方式。
特点 快速的、轻量级、只读的,遍历访问每一行数据的数据流 向一个方向,一行一行地读取,不能向后读取,不能修改数据。
缺点:不灵活,只适合数据量小的情况,只限于读取数据,一直占用连接
读取方式:Read()获取第一行的数据,再次调用Read()方法,当调用Read()方法返回False时,就表示不再有数据行。
注意:
连接对象一直保持Open状态,如果连接关闭,是不能读取数据的。使用完成过后,应该马上调用close()关闭,不然Reader对象会一直占用连接。
创建方式:是不能直接构造,cmd.ExecuteReader()来创建。cmd.ExecuteReader(CommandBehavior.CloseConnection)—-好处:关闭reader对象的时候就会自动关闭数据库连接。
读取时尽量使用与数据库字段类型相匹配的方法来取得对应的值,会减少因类型不一致而增加类型转换操作的性能损耗。
没有读取到末尾就要关闭reader对象时,先调用cmd.Cancel()方法,然后在调用reader.Close()
cmd.ExecuteReader()获取存储过程的返回值或输出参数,先调用reader.close(),然后才能获取参数的值。
常用属性:
Connection:获取与reader对象相关的sqlconnection
FieldCount:当前行中的列数。
HasRows:reader是否包含一行还是多行。
IsClosed:reader对象是否已关闭
Item[int]:列序号,给定列序号的情况,获取指定列的值 dr[1] object类型
Item[String]:列名,获取指定列的值
应用
常用方法
Close() 关闭dr
GetInt32(列序号)—根据数据类型相匹配的方法
GetFieldType(列序号) 获取数据类型的Type
GetName(列序号)
GetOrdinal(列名) 获取指定列名的列序号
Read() 使dr前进到下一条记录
NextResult() 多结果的情况下,使dr前进到下一个结果
读取
Read()
string constr = ConfigurationManager.ConnectionStrings["Constr"].ConnectionString;
using (SqlConnection con = new SqlConnection(constr))
{
string sql = "select * from student";
SqlCommand cmd = new SqlCommand(sql, con);
con.Open();//必须在执行之前
SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);//创建
if (dr.HasRows)
{
int indexId = dr.GetOrdinal("ID");//获取指定列明的列序号
//string idName = dr.GetName(0);
int indexName = dr.GetOrdinal("Sname");
int indexclassno = dr.GetOrdinal("classno");
//读一行存一行,dr读一行丢一行
while (dr.Read())//检测是否有数据
{
//int userId = (int)dr[0];//int.parse(dr[0].ToString())
//string userName = dr["Sname"].ToString();
int userId = dr.GetInt32(indexId);//int 不用再次进行拆箱操作
string userName = dr.GetString(indexName);
int classno = dr.GetInt32(indexclassno);
}
}
dr.Close();
}
string constr = ConfigurationManager.ConnectionStrings["Constr"].ConnectionString;
using (SqlConnection con = new SqlConnection(constr))
{
string sql = "select * from student";
SqlCommand cmd = new SqlCommand(sql, con);
con.Open();//必须在执行之前
SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);//创建
DataTable dt = new DataTable();
dt.Load(dr);//将dr对象加载到DataTable
dr.Close();
}
//新建一个类
namespace ConsoleApp8
{
public class Class1
{
public int ID { get; set; }
public string Sname { get; set; }
public string sex { get; set; }
public DateTime birth { get; set; }
public int classno { get; set; }
}
}
//通过list集合存储数据
string constr = ConfigurationManager.ConnectionStrings["Constr"].ConnectionString;
using (SqlConnection con = new SqlConnection(constr))
{
string sql = "select * from student";
SqlCommand cmd = new SqlCommand(sql, con);
con.Open();//必须在执行之前
SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);//创建
if (dr.HasRows)
{
int indexId = dr.GetOrdinal("ID");//获取指定列明的列序号
//string idName = dr.GetName(0);
int indexName = dr.GetOrdinal("Sname");
int indexclassno = dr.GetOrdinal("classno");
//读一行存一行,dr读一行丢一行
//list集合
List<Class1> list = new List<Class1>();
while (dr.Read())//检测是否有数据
{
Class1 model = new Class1();
model.ID = dr.GetInt32(indexId);
model.Sname = dr.GetString(indexName);
model.classno = dr.GetInt32(indexclassno);
list.Add(model);
}
}
dr.Close();
}
SqlDataReader读取数据
常用方法
Close()关闭dr
GetInt32(列序号)——根据数据类型相匹配的方法
GetFiledType(列序号)——获取数据类型的Type对象
GetName(列序号)——获取指定列的列名
GetOrdinal(列名)——获取指定列名的列序号
Read()——使dr前进到下一条记录
NextResult()——使dr前进到下一个结果
读取
Read()
数据量小的情况 高效