---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、
<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------
一、ADO.NET是什么?
在装了SQLServer服务器的机器上,可以通过SQL Management Studio来操纵数据库并且进行管理数据,实现数据的增删改查等各项功能,但是,不可能任何时候都通过设计器模式来访问数据,当我们要通过应用程序来访问数据时,就要通过ADO.NET来实现,因此,ADO.NET就是一种数据访问技术,是通过应用程序来访问数据库服务器,来获取所需要的数据或者进行操作。
二、ADO.NET基本组成
ADO.NET包含了两个重要的核心组件:数据提供程序和数据集:
1)数据提供程序
基本SQLClient类
Connection 用来连接数据库
Command 用来执行SQL语句
DataReader 只读只进的结果集
拿到查询的结果
DataAdapter 封装了上面的3个对象的对象
2)数据集
DataSet 临时数据库
断开数据库的操作
三、ADO.NET数据访问的步骤
(1)数据库的连接
首先要引用命名空间,using System.Data.SqlClient(针对SQLServer数据库)
用SqlConnection来进行连接,这时需要用到连接字符串
连接字符串内包括:
1)用SqlServer身份验证登录
server=服务器名称,database=要连接的数据库,user=用户名,password=密码
连接字符串一般包括以上几项内容。
示例:
string connstr = @"server=ZCH-PC\SQLEXPRESS;database=D_test;user=sa;password=123456";
2)用windows身份验证登录
Server=服务器名称,database=要连接的数据库,Integrated Security=true;
示例:
string connstr = @"server=ZCH-PC\SQLEXPRESS;database=D_test;Integrated Security";
3)连接字符串的其他写法:
Server的值可以改成ip地址,这样就通过网络访问其他主机上的数据库了。还可以改成.\数据库名来访问本地数据库
Server 还可以用Data source ,database可以写成initial catalog,user 简写成uid ,password简写成pwd
例如:string connstr=@”data source=”服务器名;initial catalog =数据库名;uid=sa;pwd=123”;
连接的两种方式:
1)SqlConnection 连接变量名=new SqlConnection() ---使用无参数的构造函数来连接
String 连接字符串=“............”;
conn.ConnectionString=连接字符串;
连接变量名.Open() ; --调用open() 来打开数据库连接
string connstr = @"server=ZCH-PC\SQLEXPRESS;database=D_test;user=sa;password=123456";
SqlConnection conn = new SqlConnection();
conn.ConnectionString = connstr;
conn.Open();
示例:
2)定义连接字符串 String 连接字符串=“.............”
SqlConnection 连接变量名=new SqlConnection(连接字符串) --使用有参数的构造函数,写入连接字符串
连接变量名.Open()
string connstr = @"server=ZCH-PC\SQLEXPRESS;database=D_test;user=sa;password=123456";
SqlConnection conn = new SqlConnection(connstr);
conn.Open();
不管采用哪个构造函数,最后都要调用Open()方法。
3)如果连接字符串写在了程序中,那么就相当于固定了,如果服务器改变了,就要修改应用程序,这时,为了方便,可以单独新建一个App.config配置文件,写入连接字符串,如果有什么变化,直接修改配置文件即可,不用改动应用程序。
配置文件:App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings> <addconnectionString="Datasource=ZCH-PC\SQLEXPRESS;database=master;user=sa;password=123456" name="connstr1"/>
</connectionStrings> //添加连接字符串
</configuration>
在写入配置文件之后,可以引入该类库。
配置文件的引用:打开要使用字符串的项目,选中“引用”单机右键,选择“添加引用”,在弹出的对话框中,选择“.net”,找到“System.Configuration”后,点击确定。这时,打开Program.cs,在项目中,加入命名空间的引用,就可以使用该命名空间下的ConfigurationManager类进行配置文件的引用了。
在配置文件中,可以写入多个连接字符串
4)连接成功之后,就可以执行各项操作了,这是有一个属性state可以查看连接的状态。
(2)Close()与 Dispose()
凡是有Dispose()方法的类型,需要在执行后dispose(),一般访问非托管资源的时候,才会实现dispose接口。
因为数据库的连接要占用很大的资源,而数据库是稀有资源,因此,当程序执行完之后,要释放资源,因此,要用到close() 与dispose()
Close():数据库的连接关闭,但是资源还被占用着,因此关闭之后还可以在调用OPEN()打开连接。
Dispose():数据库资源的释放,相当于销毁了一个连接,调用了Dispose()之后不能再打开了。
为了方便,使用Using可以自动的释放资源。
用法:Using (连接的对象){要执行的语句}
当{}内的语句块执行结束后,自动调用dispose(),因此,自动释放()内的连接对象。
示例:
static void Main(string[] args)
{
int result = 0;
string sql = "select count(*) from [dbo].[Student]";
string connstr = ConfigurationManager.ConnectionStrings["connstr"].ConnectionString;
using (SqlConnection conn = new SqlConnection(connstr))
{
using (SqlCommand cmd = new SqlCommand(sql,conn))
{
if (conn.State == ConnectionState.Closed)
{
try
{
conn.Open();
result = (int)cmd.ExecuteScalar();
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
}
}
}
Console.WriteLine("查询到的结果是:{0}", result);
Console.ReadKey();
}
}
(3)输入SQL语句
写入SQL语句需要用到的类是SqlCommand,
(1)用法:SqlCommand 变量名=new SqlCommand();
示例:
SqlCommand 类的构造方法有三种重载,最常用的是传入sql语句字符串和加入要连接的实例:string sql = "select count(*) from [dbo].[Student]";
string connstr=ConfigurationManager.ConnectionStrings["connstr"].ConnectionString;
SqlConnection conn = new SqlConnection();
conn.ConnectionString =connstr;
SqlCommand cmd = new SqlCommand(sql,conn); //使用了两个参数的构造方法
conn.Open();
(2)SqlCommand 变量名=new SqlCommand (SQL语句字符串,连接对象)
也可以使用无参数的Sqlcommand,这是需要调用对象的connection来传入要连接的对象和调用对象的commandText来传入查询语句。
string sql = "select count(*) from [dbo].[Student";
string connstr=ConfigurationManager.ConnectionStrings["connstr"].ConnectionString;
SqlConnection conn = new SqlConnection();
conn.ConnectionString =connstr;
SqlCommand cmd = new SqlCommand(); //使用了无参数的构造函数。
cmd.Connection = conn; //需要调用这样的方法来赋值
cmd.CommandText = sql;
conn.Open();
(4)Sql语句执行,返回结果:用SqlCommand 的对象来调用下面的方法。
传入SQL命令后,需要来执行,这就用到了执行方法:
1)ExecuteScalar() //用作查询只返回一行一列结果,单值查询
示例:int result=0;
string sql = "select count(*) from [dbo].[StudentShiWan]"; //该条语句执行后返回一个值
string connstr=ConfigurationManager.ConnectionStrings["connstr"].ConnectionString;
qlConnection conn = new SqlConnection();
conn.ConnectionString =connstr;
SqlCommand cmd = new SqlCommand(sql,conn);
conn.Open();
result =(int)cmd.ExecuteScalar(); //执行查询,因为结果是object类型,需要拆箱操作
Console.WriteLine("结果是:{0}",result);
Console.ReadKey();
2)ExecuteNonQuery()//不返回结果集,只执行命令,返回受影响的行数(执行行数)一般不用做查询,执行插入,删除修改等操作。
ExecuteNonQuery用法示例:
static void Main(string[] args)
{
int num; //定义一个int类型的变量,用作接收受影响行数的
string connstr=ConfigurationManager.ConnectionStrings["connstr"].ConnectionString;
SqlConnection conn = new SqlConnection(connstr);
using(conn) //使用using()来执行完语句后释放连接对象
{
using (SqlCommand cmd = new SqlCommand())
{
try
{
if (conn.State == ConnectionState.Closed)
{
conn.Open(); //调用open()方法打开数据库连接
cmd.CommandText = "update[dbo].[studentinfomation] set address='上海'";
num = cmd.ExecuteNonQuery(); //使用了“执行”命令
Console.WriteLine("{0}行受影响!!~~", num);
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
Console.ReadKey();
因为ExecuteNonQuery()的执行是不返回结果集的,所以,一般用作数据库的增删改,不用做查询,这个例子中,只要修改一下SQL语句,就可以返回增加,修改,查询的受影响的行数了。
3)ExecuteReader() //用作查询,返回DataReader对象。
1、在执行了ExecuteReader()方法之后,要定义一个DataReader 实例来接收它的值,
DataReader 实例名 =ExecuteReader();
2、虽然返回了一个DataReader类型的对象,它只返回一些数据信息,但数据本身不再对象里,要通过调用其他方法来获取数据。
3、DataReader 的实例在读取数据时,是一条一条的来读取的,当查询到数据时,数据在数据库内存中,每调用一次read()方法,内存的指针向下移一次,来读取每一行数据。
重要的属性:
1)HasRow;布尔类型了值,如果有值返回true,如果没有值,返回false,能够做出有没有读到数据的判断。
2)FieldCount:返回字段的总数
3)RecondsAffected::当用ExecuteReader来执行增,删,改的操作时,返回受影响的行数
常用的方法:
1)read():获取每一行数据。//可以传入要读取的列名或者列序号来获取指定列。
2)Dispose()该实例有dispose()方法,因此,要在运行结束时释放资源,可放入using()里使用。
3)GetString(int i):在调用时,传入列的序号,就可以返回该列的字符串。
4)GetName(int i):传入列的序号,获取列的名称。
5)GetOrdinary(string s):传入列的名称,获取列的序号。
调用ExecuteReader()方法的示例:
...................................................................
static void Main(string[] args)
{
Console.WindowWidth = 170;
Console.WindowHeight = 44;
string sql ="select * from mybook"; //要查询的sql语句字符串
string connstr = ConfigurationManager.ConnectionStrings["connstr"].ConnectionString; //读取配置文件中的连接字符串。
using (SqlConnection conn = new SqlConnection(connstr)) //创建连接对象
{
if (conn.State == ConnectionState.Closed) //判断数据库连接状态,如果是
{ //关闭状态就开发
try{
conn.Open();
using (SqlCommand cmd = new SqlCommand(sql, conn))/ { //创建sqlcommand对象。
using (SqlDataReader reader = cmd.ExecuteReader())
{ //执行sql并返回sqldatareader
if (reader.HasRows)
{ //判断是否有数据
while (reader.Read()) //如果有数据就获取一行的数据
{
for (int i = 0; i < reader.FieldCount; i++)
{
object o = reader[i];//获取每个字段的数据并
Console.Write(o.ToString()+"\t");//打印出来
}
Console.WriteLine();
}
}
}
}
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
}
}
}
总结获取数据的步骤:
1)首先,调用ExecuteReader()方法返回sqldatareader实例
1)用hasrow属性判断查询结果是否存在数据
2)如果存在,就循环调用read()方法来获取每一行数据
3)利用索引,或者GetString(),GetValue(),或者通过循环FieldCount;获取每一行、每个字段或者指定字段的值。
四、DateSet离线数据库
DateSet就是在与数据库断开的情况下,进行访问数据,这是因为,把数据导入到dateset的临时内存中,不过,不适合在有大量的数据的情况先使用,因为,这会加重本地内存的负担。
实现离线数据库访问有两个很重要的类
(1)DateSet把数据库中的数据一次性导入到DateSet从而,就可以断开数据库的连接。
(2)SqlDataAdapter该类的一个实例通过调用fill()方法,把数据填充到dataset中。
填充后的数据集包括的内容:
一个数据库中可以有多张表,因此,一个数据集也可以有多张表。
不仅包含表,还有每张表的行属性,列属性等
DataTable 类代表数据库的一张表
DataRow类代表数据库中,一张表的一行数据
DataColumn类代表数据库中,一张表的一列数据
示例:
static void Main(string[] args)
{
Console.WindowHeight = 44;
Console.WindowWidth = 170;
string connstr=ConfigurationManager.ConnectionStrings["connstr"].ConnectionString;
string sql = "select * from mybook;select * from MyBooks"; //sql连接字符串与查询语句
DataSet dataset = new DataSet("book"); //新建离线数据集
try
{
using (dataset)
{
SqlDataAdapter adapter = new SqlDataAdapter(sql, connstr);
using (adapter) //新建SqlDataAdapter
{ //并传入sql语句,和连接字符串
adapter.Fill(dataset); //SqlDataAdapter对象调用Fill()填充Dataset
DataTable dtmybook = dataset.Tables[0]; //把第一个表赋给DataTable类
for (int i = 0; i < dtmybook.Rows.Count; i++) //的实例
{ //通过循环遍历每一行并获取数据
DataRow row = dtmybook.Rows[i];
for (int j = 0; j < dtmybook.Columns.Count; j++) //通过循环遍历没一
{ //列数据
Console.Write(row[j]+"\t"); //打印每行每列数据
}
Console.WriteLine();
}
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadKey();
}
五、参数化数据查询
由于SQL注入漏洞等安全问题,不在使用拼接字符串的方法来实现SQL语句来进行查询,而是通过传入参数来执行SQL语句。
用到的类SqlPrarmeter
查询SQL语句方式:
Select 要查询的字段名 from 表名 where 条件=“@参数”
例如:Select price from Book where bookname=”@bookname” ;
再通过SqlCommand 对象,把参数加进去。
例如:SqlCommand cmd =new SqlCommand();
cmd.Parameters.Add( SqlParameter类型对象)
通过这样的参数传入之后,在调用一些执行的方法来进行数据库操作:
示例:下面是一个执行SQL插入数据的例子:(只有部分代码:)
string user = txtname.Text.Trim();
string pwd = txtpwd.Text.Trim();
String sql=string.Format("insert into UserLogin (username,userpassword) values(@username,@userpassword)"); //定义了两个参数
SqlParameter [] sqls=new SqlParameter []{new SqlParameter("@username",user),new SqlParameter ("@userpassword",pwd)}; //SqlParameter类型的数组,定义了参数和相关的值
try
{
int result = Register(sql, sqls); //Register()是双线下面的方法
MessageBox.Show(string.Format("成功插入了{0}条数据", result));
}
================================================================================
public static int Register(string sql, SqlParameter[] sqlparams)//要调用该方法,要传入两个类型的
{ //参数,返回受影响的行数
int result=-1;
try
{
using (SqlConnection conn = new SqlConnection(connstr))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
foreach (SqlParameter sqlpara in sqlparams)
{
cmd.Parameters.Add(sqlpara); //Sqlcommand对象把参数一个一个
} //的加入进去
result = cmd.ExecuteNonQuery();
}
}
}
catch(Exception ex)
{
throw new Exception(ex.Message);
}
return result;
}
---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、
<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------