[C#学习笔记25]ADO.NET完成CRUD、配置问题分析、通用Helper编写
基于ADO.NET实现快速高效的数据访问
一、应用程序和数据库链接条件
1、服务器IP地址(练习时在本机,直接用服务器名称)
2、数据库名称
3、登陆账号
4、登陆密码
PS:关于数据库操作的对象
SQLServer MySql Oracle Access Excel
解决数据库连接用的是统一的“接口”的不同实现
SqlConnection SqlCommand SqlDataReader
MySqlConnection 【需要你单独添加第三方的dll】
OracleConnection... 【需要你单独添加第三方的dll】
OleDbConnection...
链接的条件:把连接条件封装到一个字符串中。
二、基于ADO.NET实现增删改查核心操作
use CourseManageDB
go
select * from Course
select Count(*) as 课程总数 from Course
select CourseName from Course where CourseId=1043
select CourseName, CourseContent, ClassHour from Course where CourseId<1020
三、通用数据访问类SQLHelper的使用
1.编写通用的增删改方法。
2.关于字符配置问题。常见错误如下:
System.TypeInitializationException:““xiketang.com.Ado.Net.SQLHelper”的类型初始值设定项引发异常。”
解决方法:
【1】项目的配置文件App.config,不能重复添加,而且名称不能修改!
【2】xml文件节点名称写错
<connectionString>
<add name="connString" connectionString="Server=.;DataBase=CourseManageDB;Uid=sa;Pwd=a123456"/>
</connectionString>
少了一个s,应该是connectionStrings
【3】配置节点中,name部分写错,比如多了一个空格
<add name="connString " connectionString="Server=.;DataBase=CourseManageDB;Uid=sa;Pwd=a123456"/>
"connString " 这个地方有空格和没有空格是有区别的。
【4】配置节点中,name部分单词拼写错误,比如
name="connStrig" 当我们使用connString的时候,就找不到了。
【5】配置节点写的正确,但是读取的时候,C#部分,节点名写错
private static string connString = ConfigurationManager.ConnectionStrings["conString"].ToString();
比如上面conString少了一个n,记住,在这个地方和前面一样,多一个空格也不行!
【6】配置文件App.config文件必须放到项目的“可启动项目的根目录下”,不能放到其他模块下面!
比如把此文件,放到DAL或其他类库下面,都是不允许的。
3.封装单一结果查询方法
4.封装结果集查询方法
错误:System.InvalidOperationException:“阅读器关闭时尝试调用 Read 无效。”
原因:是我们在通用方法中关闭了链接,我们不能直接关闭,解决方法如下:
添加枚举 return cmd.ExecuteReader(CommandBehavior.CloseConnection);
特别说明:
我们不能把链接对象Connection再次独立了。因为我们使用的静态方法,否则会出现冲突。
添加类SQLHelper.cs内容如下
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SQLTest
{
class SQLHelper
{
//private static string connString = "server=.;database=CourseManageDB;uid=sa;pwd=123456";
private static string connString = ConfigurationManager.ConnectionStrings["connString"].ToString();
/// <summary>
/// 通用数据访问类
/// 执行增删改的方法
/// 封装变化的作为参数,抽取不变的作为方法。
/// </summary>
public static int Update(string sql)
{
//[1]创建连接对象
SqlConnection conn = new SqlConnection(connString);
//[2]创建Command对象
SqlCommand cmd = new SqlCommand(sql, conn);
try
{
//[3]打开数据库的连接
conn.Open();
//[4]执行操作(下面这个方法,只能用于执行insert、update、delete操作,不能执行select)
return cmd.ExecuteNonQuery();
//Console.WriteLine("受影响行数:" + result);
}
catch (Exception ex)
{
//捕获ex对象相关信息保存到日志文件中
throw new Exception("执行方法public static int Update(string sql)发生异常:" + ex.Message);
}
finally//不论是否发生异常都要执行的代码
{
//[5]关闭连接
conn.Close();
}
}
/// <summary>
/// 执行单一结果查询返回方法
/// </summary>
/// <param name="sql"></param>
/// <returns></returns>
public static object GetSingleResult(string sql)
{
//[1]创建连接对象
SqlConnection conn = new SqlConnection(connString);
//[2]创建Command对象
SqlCommand cmd = new SqlCommand(sql, conn);
try
{
//[3]打开数据库的连接
conn.Open();
//[4]执行操作(下面这个方法,只能用于执行insert、update、delete操作,不能执行select)
return cmd.ExecuteScalar();
//Console.WriteLine("受影响行数:" + result);
}
catch (Exception ex)
{
//捕获ex对象相关信息保存到日志文件中
throw new Exception("执行方法public static int GetSingleResult(string sql)发生异常:" + ex.Message);
}
finally//不论是否发生异常都要执行的代码
{
//[5]关闭连接
conn.Close();
}
}
/// <summary>
/// 返回结果集查询
/// </summary>
/// <param name="sql"></param>
/// <returns></returns>
public static SqlDataReader GetReader(string sql)
{
//[1]创建连接对象
SqlConnection conn = new SqlConnection(connString);
//[2]创建Command对象
SqlCommand cmd = new SqlCommand(sql, conn);
try
{
//[3]打开数据库的连接
conn.Open();
//[4]执行操作(下面这个方法,只能用于执行insert、update、delete操作,不能执行select)
//添加枚举CommandBehavior.CloseConnection之后,reader对象的链接会跟随reader对象的关闭自动关闭
return cmd.ExecuteReader(CommandBehavior.CloseConnection);
//Console.WriteLine("受影响行数:" + result);
}
catch (Exception ex)
{
//捕获ex对象相关信息保存到日志文件中
throw new Exception("执行方法public static int GetReader(string sql)发生异常:" + ex.Message);
}
//finally//这里不能直接关闭
//{
// //[5]关闭连接
// conn.Close();
//}
}
}
}
Program.cs内容如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//引入命名空间
using System.Data.SqlClient;
using System.Data;
namespace SQLTest
{
class Program
{
static void Main(string[] args)
{
//ConnectDB();
//ExecuteInsert();
//ExecuteUpdate();
//ExecuteDelete();
//ExecuteSingleResult();
//ExecuteReader();
//ExecuteInsertByHelper();
//ExecuteSingleResultByHelper();
ExecuteReaderByHelper();
Console.Read();
}
static void ConnectDB()
{
//创建数据库连接对象
string connString = "server=.;database=CourseManageDB;uid=sa;pwd=123456";
SqlConnection conn = new SqlConnection(connString);
conn.Open();
if (conn.State == ConnectionState.Open)
Console.WriteLine("打开成功!");
conn.Close();
if (conn.State == ConnectionState.Closed)
Console.WriteLine("关闭成功!");
}
static void ExecuteInsert()
{
//[1]创建连接对象
string connString = "server=.;database=CourseManageDB;uid=sa;pwd=123456";
SqlConnection conn = new SqlConnection(connString);
//定义sql语句
string sql = "Insert into Course(CourseName,CourseContent,ClassHour,Credit,CategoryId,TeacherId)";
sql += "values ('.Net全栈','C#基础',500,12,10,100)";
//[2]创建Command对象
//SqlCommand cmd = new SqlCommand();
//cmd.CommandText = sql;
//cmd.Connection = conn;等效于
SqlCommand cmd = new SqlCommand(sql,conn);
//[3]打开数据库的连接
conn.Open();
//[4]执行操作(下面这个方法,只能用于执行insert、update、delete操作,不能执行select)
int result = cmd.ExecuteNonQuery();
Console.WriteLine("受影响行数:"+result);
//[5]关闭连接
conn.Close();
}
static void ExecuteUpdate()
{
//[1]创建连接对象
string connString = "server=.;database=CourseManageDB;uid=sa;pwd=123456";
SqlConnection conn = new SqlConnection(connString);
//定义sql语句
string sql = "Update Course set CourseName='.NET高级',CourseContent='更高级',ClassHour=20,CategoryId=10,TeacherId=101";
sql += "where CourseId=18 and Credit=12";
//[2]创建Command对象
SqlCommand cmd = new SqlCommand(sql, conn);
//[3]打开数据库的连接
conn.Open();
//[4]执行操作(下面这个方法,只能用于执行insert、update、delete操作,不能执行select)
int result = cmd.ExecuteNonQuery();
Console.WriteLine("受影响行数:" + result);
//[5]关闭连接
conn.Close();
}
static void ExecuteDelete()
{
//[1]创建连接对象
string connString = "server=.;database=CourseManageDB;uid=sa;pwd=123456";
SqlConnection conn = new SqlConnection(connString);
//定义sql语句
string sql = "Delete Course ";
sql += "where CourseId=18 and Credit=12";
//[2]创建Command对象
SqlCommand cmd = new SqlCommand(sql, conn);
//[3]打开数据库的连接
conn.Open();
//[4]执行操作(下面这个方法,只能用于执行insert、update、delete操作,不能执行select)
int result = cmd.ExecuteNonQuery();
Console.WriteLine("受影响行数:" + result);
//[5]关闭连接
conn.Close();
}
//执行单一结果的查询
static void ExecuteSingleResult()
{
//[1]创建连接对象
string connString = "server=.;database=CourseManageDB;uid=sa;pwd=123456";
SqlConnection conn = new SqlConnection(connString);
//定义sql语句
string sql = "select Count(*) as 课程总数 from Course ";
//[2]创建Command对象
SqlCommand cmd = new SqlCommand(sql, conn);
//[3]打开数据库的连接
conn.Open();
//[4]执行查询
object result = cmd.ExecuteScalar();
Console.WriteLine("查询结果:" + result);
//[5]关闭连接
conn.Close();
}
static void ExecuteReader()
{
//[1]创建连接对象
string connString = "server=.;database=CourseManageDB;uid=sa;pwd=123456";
SqlConnection conn = new SqlConnection(connString);
//定义sql语句
string sql = "select CourseName,CourseContent,ClassHour from Course where CourseId<13";
//[2]创建Command对象
SqlCommand cmd = new SqlCommand(sql, conn);
//[3]打开数据库的连接
conn.Open();
//[4]执行查询
SqlDataReader result = cmd.ExecuteReader();
//判断是否有查询结果来决定读取数据
while (result.Read())
{
Console.WriteLine($"{result["CourseName"]}\t{result[1]}\t{result["ClassHour"]}");
}
result.Close();//关闭读取器对象
//[5]关闭连接
conn.Close();
}
static void ExecuteInsertByHelper()
{
string sql = "Insert into Course(CourseName,CourseContent,ClassHour,Credit,CategoryId,TeacherId)";
sql += "values ('.Net全栈1','C#基础1',500,12,10,102)";
int result = SQLHelper.Update(sql);
Console.WriteLine("受影响行数:"+result);
}
static void ExecuteSingleResultByHelper()
{
string sql = "select Count(*) as 课程总数 from Course";
object result = SQLHelper.GetSingleResult(sql);
Console.WriteLine(result);
}
static void ExecuteReaderByHelper()
{
//定义sql语句
string sql = "select CourseName,CourseContent,ClassHour from Course where CourseId<13";
//[4]执行查询
SqlDataReader reader = SQLHelper.GetReader(sql);
//判断是否有查询结果来决定读取数据
while (reader.Read())
{
Console.WriteLine($"{reader["CourseName"]}\t{reader[1]}\t{reader["ClassHour"]}");
}
reader.Close();//关闭读取器对象,执行关闭时会先自动把它使用的链接对象关闭
}
}
}

