[C#學(xué)習(xí)筆記25]ADO.NET完成CRUD、配置問題分析、通用Helper編寫
基于ADO.NET實現(xiàn)快速高效的數(shù)據(jù)訪問
一、應(yīng)用程序和數(shù)據(jù)庫鏈接條件
1、服務(wù)器IP地址(練習(xí)時在本機,直接用服務(wù)器名稱)
2、數(shù)據(jù)庫名稱
3、登陸賬號
4、登陸密碼
PS:關(guān)于數(shù)據(jù)庫操作的對象
SQLServer MySql Oracle ? ? Access ? Excel
解決數(shù)據(jù)庫連接用的是統(tǒng)一的“接口”的不同實現(xiàn)
SqlConnection ? ?SqlCommand ? ?SqlDataReader
MySqlConnection 【需要你單獨添加第三方的dll】
OracleConnection... ?【需要你單獨添加第三方的dll】
OleDbConnection...
鏈接的條件:把連接條件封裝到一個字符串中。
二、基于ADO.NET實現(xiàn)增刪改查核心操作
use CourseManageDB
go
select * from Course
select Count(*) as 課程總數(shù) from Course
select CourseName from Course where CourseId=1043
select CourseName, CourseContent, ClassHour from Course where CourseId<1020
三、通用數(shù)據(jù)訪問類SQLHelper的使用
1.編寫通用的增刪改方法。
2.關(guān)于字符配置問題。常見錯誤如下:
System.TypeInitializationException:““xiketang.com.Ado.Net.SQLHelper”的類型初始值設(shè)定項引發(fā)異常?!?/p>
解決方法:
【1】項目的配置文件App.config,不能重復(fù)添加,而且名稱不能修改!
【2】xml文件節(jié)點名稱寫錯
<connectionString>
<add name="connString" connectionString="Server=.;DataBase=CourseManageDB;Uid=sa;Pwd=a123456"/>
</connectionString>
少了一個s,應(yīng)該是connectionStrings
【3】配置節(jié)點中,name部分寫錯,比如多了一個空格
<add name="connString " connectionString="Server=.;DataBase=CourseManageDB;Uid=sa;Pwd=a123456"/>
"connString " 這個地方有空格和沒有空格是有區(qū)別的。
【4】配置節(jié)點中,name部分單詞拼寫錯誤,比如
name="connStrig" ?當(dāng)我們使用connString的時候,就找不到了。
【5】配置節(jié)點寫的正確,但是讀取的時候,C#部分,節(jié)點名寫錯
private static string connString = ConfigurationManager.ConnectionStrings["conString"].ToString();
比如上面conString少了一個n,記住,在這個地方和前面一樣,多一個空格也不行!
【6】配置文件App.config文件必須放到項目的“可啟動項目的根目錄下”,不能放到其他模塊下面!
比如把此文件,放到DAL或其他類庫下面,都是不允許的。
3.封裝單一結(jié)果查詢方法
4.封裝結(jié)果集查詢方法
錯誤:System.InvalidOperationException:“閱讀器關(guān)閉時嘗試調(diào)用 Read 無效?!?/p>
原因:是我們在通用方法中關(guān)閉了鏈接,我們不能直接關(guān)閉,解決方法如下:
添加枚舉 ?return cmd.ExecuteReader(CommandBehavior.CloseConnection);
特別說明:
我們不能把鏈接對象Connection再次獨立了。因為我們使用的靜態(tài)方法,否則會出現(xiàn)沖突。
添加類SQLHelper.cs內(nèi)容如下
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>
/// 通用數(shù)據(jù)訪問類
/// 執(zhí)行增刪改的方法
/// 封裝變化的作為參數(shù),抽取不變的作為方法。
/// </summary>
public static int Update(string sql)
{
//[1]創(chuàng)建連接對象
SqlConnection conn = new SqlConnection(connString);
//[2]創(chuàng)建Command對象
SqlCommand cmd = new SqlCommand(sql, conn);
try
{
//[3]打開數(shù)據(jù)庫的連接
conn.Open();
//[4]執(zhí)行操作(下面這個方法,只能用于執(zhí)行insert、update、delete操作,不能執(zhí)行select)
return cmd.ExecuteNonQuery();
//Console.WriteLine("受影響行數(shù):" + result);
}
catch (Exception ex)
{
//捕獲ex對象相關(guān)信息保存到日志文件中
throw new Exception("執(zhí)行方法public static int Update(string sql)發(fā)生異常:" + ex.Message);
}
finally//不論是否發(fā)生異常都要執(zhí)行的代碼
{
//[5]關(guān)閉連接
conn.Close();
}
}
/// <summary>
/// 執(zhí)行單一結(jié)果查詢返回方法
/// </summary>
/// <param name="sql"></param>
/// <returns></returns>
public static object GetSingleResult(string sql)
{
//[1]創(chuàng)建連接對象
SqlConnection conn = new SqlConnection(connString);
//[2]創(chuàng)建Command對象
SqlCommand cmd = new SqlCommand(sql, conn);
try
{
//[3]打開數(shù)據(jù)庫的連接
conn.Open();
//[4]執(zhí)行操作(下面這個方法,只能用于執(zhí)行insert、update、delete操作,不能執(zhí)行select)
return cmd.ExecuteScalar();
//Console.WriteLine("受影響行數(shù):" + result);
}
catch (Exception ex)
{
//捕獲ex對象相關(guān)信息保存到日志文件中
throw new Exception("執(zhí)行方法public static int GetSingleResult(string sql)發(fā)生異常:" + ex.Message);
}
finally//不論是否發(fā)生異常都要執(zhí)行的代碼
{
//[5]關(guān)閉連接
conn.Close();
}
}
/// <summary>
/// 返回結(jié)果集查詢
/// </summary>
/// <param name="sql"></param>
/// <returns></returns>
public static SqlDataReader GetReader(string sql)
{
//[1]創(chuàng)建連接對象
SqlConnection conn = new SqlConnection(connString);
//[2]創(chuàng)建Command對象
SqlCommand cmd = new SqlCommand(sql, conn);
try
{
//[3]打開數(shù)據(jù)庫的連接
conn.Open();
//[4]執(zhí)行操作(下面這個方法,只能用于執(zhí)行insert、update、delete操作,不能執(zhí)行select)
//添加枚舉CommandBehavior.CloseConnection之后,reader對象的鏈接會跟隨reader對象的關(guān)閉自動關(guān)閉
return cmd.ExecuteReader(CommandBehavior.CloseConnection);
//Console.WriteLine("受影響行數(shù):" + result);
}
catch (Exception ex)
{
//捕獲ex對象相關(guān)信息保存到日志文件中
throw new Exception("執(zhí)行方法public static int GetReader(string sql)發(fā)生異常:" + ex.Message);
}
//finally//這里不能直接關(guān)閉
//{
// ? ?//[5]關(guān)閉連接
// ? ?conn.Close();
//}
}
}
}
Program.cs內(nèi)容如下:
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()
{
//創(chuàng)建數(shù)據(jù)庫連接對象
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("關(guān)閉成功!");
}
static void ExecuteInsert()
{
//[1]創(chuàng)建連接對象
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#基礎(chǔ)',500,12,10,100)";
//[2]創(chuàng)建Command對象
//SqlCommand cmd = new SqlCommand();
//cmd.CommandText = sql;
//cmd.Connection = conn;等效于
SqlCommand cmd = new SqlCommand(sql,conn);
//[3]打開數(shù)據(jù)庫的連接
conn.Open();
//[4]執(zhí)行操作(下面這個方法,只能用于執(zhí)行insert、update、delete操作,不能執(zhí)行select)
int result = cmd.ExecuteNonQuery();
Console.WriteLine("受影響行數(shù):"+result);
//[5]關(guān)閉連接
conn.Close();
}
static void ExecuteUpdate()
{
//[1]創(chuàng)建連接對象
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]創(chuàng)建Command對象
SqlCommand cmd = new SqlCommand(sql, conn);
//[3]打開數(shù)據(jù)庫的連接
conn.Open();
//[4]執(zhí)行操作(下面這個方法,只能用于執(zhí)行insert、update、delete操作,不能執(zhí)行select)
int result = cmd.ExecuteNonQuery();
Console.WriteLine("受影響行數(shù):" + result);
//[5]關(guān)閉連接
conn.Close();
}
static void ExecuteDelete()
{
//[1]創(chuàng)建連接對象
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]創(chuàng)建Command對象
SqlCommand cmd = new SqlCommand(sql, conn);
//[3]打開數(shù)據(jù)庫的連接
conn.Open();
//[4]執(zhí)行操作(下面這個方法,只能用于執(zhí)行insert、update、delete操作,不能執(zhí)行select)
int result = cmd.ExecuteNonQuery();
Console.WriteLine("受影響行數(shù):" + result);
//[5]關(guān)閉連接
conn.Close();
}
//執(zhí)行單一結(jié)果的查詢
static void ExecuteSingleResult()
{
//[1]創(chuàng)建連接對象
string connString = "server=.;database=CourseManageDB;uid=sa;pwd=123456";
SqlConnection conn = new SqlConnection(connString);
//定義sql語句
string sql = "select Count(*) as 課程總數(shù) from Course ";
//[2]創(chuàng)建Command對象
SqlCommand cmd = new SqlCommand(sql, conn);
//[3]打開數(shù)據(jù)庫的連接
conn.Open();
//[4]執(zhí)行查詢
object result = cmd.ExecuteScalar();
Console.WriteLine("查詢結(jié)果:" + result);
//[5]關(guān)閉連接
conn.Close();
}
static void ExecuteReader()
{
//[1]創(chuàng)建連接對象
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]創(chuàng)建Command對象
SqlCommand cmd = new SqlCommand(sql, conn);
//[3]打開數(shù)據(jù)庫的連接
conn.Open();
//[4]執(zhí)行查詢
SqlDataReader result = cmd.ExecuteReader();
//判斷是否有查詢結(jié)果來決定讀取數(shù)據(jù)
while (result.Read())
{
Console.WriteLine($"{result["CourseName"]}\t{result[1]}\t{result["ClassHour"]}");
}
result.Close();//關(guān)閉讀取器對象
//[5]關(guān)閉連接
conn.Close();
}
static void ExecuteInsertByHelper()
{
string sql = "Insert into Course(CourseName,CourseContent,ClassHour,Credit,CategoryId,TeacherId)";
sql += "values ('.Net全棧1','C#基礎(chǔ)1',500,12,10,102)";
int result = SQLHelper.Update(sql);
Console.WriteLine("受影響行數(shù):"+result);
}
static void ExecuteSingleResultByHelper()
{
string sql = "select Count(*) as 課程總數(shù) 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]執(zhí)行查詢
SqlDataReader reader = SQLHelper.GetReader(sql);
//判斷是否有查詢結(jié)果來決定讀取數(shù)據(jù)
while (reader.Read())
{
Console.WriteLine($"{reader["CourseName"]}\t{reader[1]}\t{reader["ClassHour"]}");
}
reader.Close();//關(guān)閉讀取器對象,執(zhí)行關(guān)閉時會先自動把它使用的鏈接對象關(guān)閉
}
}
}