步骤
ADO.NET 提供了丰富的数据库操作,这些操作可以分为三个步骤:
- 第一,使用
SqlConnection
对象连接数据库; - 第二,建立
SqlCommand
对象,负责SQL语句的执行和存储过程的调用; - 第三,对SQL或存储过程执行后返回的“结果”进行操作。
对返回“结果”的操作可以分为两类:
- 一是用
SqlDataReader
直接一行一行的读取数据集; - 二是
DataSet
联合SqlDataAdapter
来操作数据库。
SqlConnection对象
首先,在配置文件中保存连接字符串
<!--windows登录-->
<connectionStrings>
<add name="connection"
connectionString="data source=.; database=Sample_Test_DB; Integrated Security=SSPI"
providerName="System.Data.SqlClient" />
</connectionStrings>
<!--sa登录-->
<add key="conn" value="server=LAPTOP-SESUCEUV;database=form;uid=sa;pwd=***;" />
获取连接字符串
string connectionString= ConfigurationManager.ConnectionStrings["connection"].ConnectionString;
//必须保证conn在配置文件AppSetting里,否则会报错 null值没有ToString()方法
string AppSetting = ConfigurationManager.AppSettings["conn"].ToString();
使用SqlConnection对象连接数据库
命名空间:System.Data.SqlClient.SqlConnection;
返回数据库连接对象,参数字符串。实例化“连接对象”,
SqlConnection connection = new SqlConnection(connectionString);
使用之前打开连接,使用之后关闭连接,使用原则是尽可能晚地打开,尽可能早地关闭。
SqlCommand对象
什么时候打开,什么时候关闭呢?这时引入SqlCommand对象。
命名空间:System.Data.SqlClient.SqlCommand;
SqlCommand对象用于执行数据库操作,操作方式有三种:
- SQL语句:
command.CommandType = CommandType.Text;
- 存储过程:
command.CommandType = CommandType.StoredProcedure;
- 整张表:
command.CommandType = CommandType.TableDirect;
常用方法
-
command.ExecuteNonQuery()
:返回受影响行数,如增、删、改操作; -
command.ExecuteScalar()
:执行查询,返回首行首列的结果; -
command.ExecuteReader()
:返回一个数据流(SqlDataReader对象)。
实例化一个SqlCommand对象
SqlCommand command = new SqlCommand();
command.Connection = connection; // 绑定SqlConnection对象
//SqlCommand command = connection.CreateCommand(); //或者直接ci
常用操作
- 执行SQL
SqlCommand cmd = connection.CreateCommand(); //创建SqlCommand对象
cmd.CommandType = CommandType.Text;
cmd.CommandText = "select * from change where FileID=@FileID"; //sql语句
cmd.Parameters.Add("@FileID", SqlDbType.NVarChar);
cmd.Parameters["@FileID"].Value = "DR-200001"; //给参数sql语句的参数赋值
- 存储过程
SqlCommand cmd = conn.CreateCommand();
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.CommandText = "存储过程名";
- 整张表
SqlCommand cmd = conn.CreateCommand();
cmd.CommandType = System.Data.CommandType.TableDirect;
cmd.CommandText = "表名"
SqlDataReader对象
命名空间:System.Data.SqlClient.SqlDataReader;
SqlDataReader对象提供只读单向数据的功能,单向:只能依次读取下一条数据;只读:DataReader中的数据是只读的,不能修改;相对地DataSet中的数据可以任意读取和修改.
SqlCommand command = new SqlCommand();
command.Connection = sqlCnt;
command.CommandType = CommandType.Text;
command.CommandText = "Select * from Users";
SqlDataReader reader = command.ExecuteReader(); //执行SQL,返回一个“流”
while (reader.Read())
{
Console.Write(reader["username"]); // 打印出每个用户的用户名
}
DataSet对象
SqlDataAdapter
命名空间:System.Data.SqlClient.SqlDataAdapter;
SqlDataAdapter是SqlCommand和DataSet之间的桥梁,实例化SqlDataAdapter对象:
SqlConnection connection= new SqlConnection(connectString);
connection.Open();
// 创建SqlCommand
SqlCommand mySqlCommand = new SqlCommand();
mySqlCommand.CommandType = CommandType.Text;
mySqlCommand.CommandText = "select * from product";
mySqlCommand.Connection = connection;
// 创建SqlDataAdapter
SqlDataAdapter myDataAdapter = new SqlDataAdapter();
myDataAdapter.SelectCommand = mySqlCommand; // 为SqlDataAdapter对象绑定所要执行的SqlCommand对象
上述SQL可以简化为
SqlConnection connection= new SqlConnection(connectString);
connection.Open();
// 隐藏了SqlCommand对象的定义,同时隐藏了SqlCommand对象与SqlDataAdapter对象的绑定
SqlDataAdapter myDataAdapter = new SqlDataAdapter("select * from product", connection);
属性和方法
- myDataAdapter.SelectCommand属性:SqlCommand变量,封装Select语句;
- myDataAdapter.InsertCommand属性:SqlCommand变量,封装Insert语句;
- myDataAdapter.UpdateCommand属性:SqlCommand变量,封装Update语句;
- myDataAdapter.DeleteCommand属性:SqlCommand变量,封装Delete语句。
- myDataAdapter.fill():将执行结果填充到Dataset中,会隐藏打开SqlConnection并执行SQL等操作。
SqlCommandBuilder
命名空间:System.Data.SqlClient.SqlCommandBuilder。
对DataSet的操作(更改、增加、删除)仅是在本地修改,若要提交到“数据库”中则需要SqlCommandBuilder对象。用于在客户端编辑完数据后,整体一次更新数据。具体用法如下:
SqlCommandBuilder mySqlCommandBuilder = new SqlCommandBuilder(myDataAdapter);
// 为myDataAdapter赋予SqlCommandBuilder功能
myDataAdapter.Update(myDataSet, "表名");
// 向数据库提交更改后的DataSet,第二个参数为DataSet中的存储表名,并非数据库中真实的表名(二者在多数情况下一致)。
DataSet
命名空间:System.Data.DataSet。
数据集,本地微型数据库,可以存储多张表。
使用DataSet第一步就是将SqlDataAdapter返回的数据集(表)填充到Dataset对象中:
SqlDataAdapter myDataAdapter = new SqlDataAdapter("select * from product", connection);
DataSet myDataSet = new DataSet();
// 创建DataSet
myDataAdapter.Fill(myDataSet, "product");
// 将返回的数据集作为“表”填入DataSet中,表名可以与数据库真实的表名不同,并不影响后续的增、删、改等操作
- 访问DataSet中的数据
SqlDataAdapter myDataAdapter = new SqlDataAdapter("select * from product", connection);
DataSet myDataSet = new DataSet();
myDataAdapter.Fill(myDataSet, "product");
//product是设置的表名
DataTable myTable = myDataSet.Tables["product"];
foreach (DataRow myRow in myTable.Rows) {
foreach (DataColumn myColumn in myTable.Columns) {
Console.WriteLine(myRow[myColumn]);
//遍历表中的每个单元格
}
}
- 修改DataSet中的数据。
SqlDataAdapter myDataAdapter = new SqlDataAdapter("select * from product", connection);
DataSet myDataSet = new DataSet();
myDataAdapter.Fill(myDataSet, "product");
// 修改DataSet
DataTable myTable = myDataSet.Tables["product"];
foreach (DataRow myRow in myTable.Rows) {
myRow["name"] = myRow["name"] + "商品";
}
// 将DataSet的修改提交至“数据库”
SqlCommandBuilder mySqlCommandBuilder = new SqlCommandBuilder(myDataAdapter);
myDataAdapter.Update(myDataSet, "product");
sqlhelper帮助类
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
namespace ajax_2.App_Code
{
public class sqlhelper
{
public static string GetSqlConnectionString()
{
string appSettings = ConfigurationManager.AppSettings["conn"];
return appSettings.ToString();
}
public static string GetConnectionString()
{
return ConfigurationManager.ConnectionStrings["connection"].ConnectionString;
}
//适合增删改操作,返回影响条数
public static int ExecuteNonQuery(string sql, params SqlParameter[] parameters)
{
using (SqlConnection conn = new SqlConnection(GetSqlConnectionString()))
{
using (SqlCommand comm = conn.CreateCommand())
{
try
{
conn.Open();
comm.CommandText = sql;
comm.Parameters.AddRange(parameters);
return comm.ExecuteNonQuery();
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
finally
{
if (conn != null && conn.State != ConnectionState.Closed)
conn.Close();
}
}
}
}
//查询操作,返回查询结果中的第一行第一列的值
public static object ExecuteScalar(string sql, params SqlParameter[] parameters)
{
using (SqlConnection conn = new SqlConnection(GetSqlConnectionString()))
{
using (SqlCommand comm = conn.CreateCommand())
{
try
{
conn.Open();
comm.CommandText = sql;
comm.Parameters.AddRange(parameters);
return comm.ExecuteScalar();
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
finally
{
if (conn != null && conn.State != ConnectionState.Closed)
conn.Close();
}
}
}
}
//Adapter调整,查询操作,返回DataTable
public static DataTable ExecuteDataTable(string sql, params SqlParameter[] parameters)
{
using (SqlDataAdapter adapter = new SqlDataAdapter(sql, GetSqlConnectionString()))
{
DataTable dt = new DataTable();
adapter.SelectCommand.Parameters.AddRange(parameters);
adapter.Fill(dt);
return dt;
}
}
public static SqlDataReader ExecuteReader(string sqlText, params SqlParameter[] parameters)
{
//SqlDataReader要求,它读取数据的时候有,它独占它的SqlConnection对象,而且SqlConnection必须是Open状态
SqlConnection conn = new SqlConnection(GetSqlConnectionString());//不要释放连接,因为后面还需要连接打开状态
SqlCommand cmd = conn.CreateCommand();
conn.Open();
cmd.CommandText = sqlText;
cmd.Parameters.AddRange(parameters);
//CommandBehavior.CloseConnection当SqlDataReader释放的时候,顺便把SqlConnection对象也释放掉
return cmd.ExecuteReader(CommandBehavior.CloseConnection);
}
/// <summary>
/// 执行查询语句,返回DataSet
/// </summary>
/// <param name="SQLString">查询语句</param>
/// <returns>DataSet</returns>
public static DataSet Query(string SQLString)
{
try
{
using (SqlConnection connection = new SqlConnection(GetConnectionString()))
{
DataSet ds = new DataSet();
try
{
connection.Open();
SqlDataAdapter command = new SqlDataAdapter(SQLString, connection);
command.Fill(ds, "ds");
}
catch (System.Data.SqlClient.SqlException ex)
{
throw new Exception(ex.Message);
}
return ds;
}
}
catch (Exception err)
{
return null;
}
}
}
}
- 问题:App_Code里面的类无法引用,原因是手动添加的App_code里类的” Build Action“ 默认是内容,只需要选择”编译“即可。
我是一个无情的搬运工,嘻嘻。