C#連接數(shù)據(jù)庫的方法
以下內(nèi)容給大家c#連接數(shù)據(jù)庫的方法的相關(guān)介紹,本文非常具有參考借鑒價值,具體詳情如下所示。
ASP.NET連接數(shù)據(jù)庫的技術(shù)叫ADO.NET,它是用來向數(shù)據(jù)庫提交sql語句的一堆類。這里連接的是Sql Server 2008數(shù)據(jù)庫,其他數(shù)據(jù)庫用法差不多,就是調(diào)用的類名不一樣。
首先在Web.config(本地的添加應(yīng)用程序配置文件App.config,本地還要添加System.Configuration.dll程序集)上配置數(shù)據(jù)庫連接字符串,添加如下節(jié)點代碼:
<connectionStrings> <add name="connstr" connectionString="Data Source=.;Initial Catalog=Milk ;User Id=sa;Password=521521521;"></add> </connectionStrings>
name是鏈接字符串名稱,可以隨便取。connectionString是鏈接字符串。Data Source數(shù)據(jù)庫所在服務(wù)器IP地址,這里是本地寫“.”。 Initial Catalog是數(shù)據(jù)庫名稱。User Id是數(shù)據(jù)庫用戶,其中sa是最高權(quán)限管理員賬戶,需要謹(jǐn)慎使用,而是針對數(shù)據(jù)庫建立數(shù)據(jù)庫的專用受限賬戶。Password是密碼。
程序使用數(shù)據(jù)庫時,先提取配置文件的連接字符串賦值給一個變量。代碼如下:
public static readonly string connstr = ConfigurationManager.ConnectionStrings["connstr"].ConnectionString;
ConfigurationManager是靜態(tài)類,提供對客戶端應(yīng)用程序配置文件的訪問。
接著打開數(shù)據(jù)庫連接,使用完畢后用using自動釋放連接:
SqlConnection是個密封類,表示 SQL Server 數(shù)據(jù)庫的一個打開的連接。接著是執(zhí)行SQL語句,先定義向數(shù)據(jù)庫發(fā)送指令用到的SqlCommand類,定義之后確定語句執(zhí)行的連接對象是conn,再確定要執(zhí)行的SQL語句,用法舉例如下:
//SqlConnection為建立和數(shù)據(jù)庫連接的對象 using(SqlConnection conn = new SqlConnection(connstr)) { conn.Open();//打開連接 //通過連接創(chuàng)建一個向數(shù)據(jù)庫發(fā)命令(Command)的對象SqlCommand using(SqlCommand cmd = conn.CreateCommand()) { cmd.CommandText =”Insert into T_Student*(Name,Age) values(‘XXX',18)”;// CommandText要執(zhí)行的SQL語句 cmd.ExecuteNonQuery();//執(zhí)行 } }
ExecuteNonQuery()一般用來執(zhí)行Update、Delete、Insert語句
對于一種一行、一列返回值的結(jié)果執(zhí)行用ExecuteScalar(),它返回object類型。舉例如下:
using(SqlConnection conn = new SqlConnection(connstr)) { conn.Open();//打開連接 //通過連接創(chuàng)建一個向數(shù)據(jù)庫發(fā)命令(Command)的對象SqlCommand using(SqlCommand cmd = conn.CreateCommand()) { cmd.CommandText =”select Name from T_Student where Name=”XXX””;// CommandText要執(zhí)行的SQL語句 cmd.ExecuteScalar();//執(zhí)行 } }
返回值有多行結(jié)果時要用ExecuteReader(),返回類型SqlDataReader,需要釋放,用法舉例:
using(SqlConnection conn = new SqlConnection(connstr)) { conn.Open();//打開連接 //通過連接創(chuàng)建一個向數(shù)據(jù)庫發(fā)命令(Command)的對象SqlCommand using(SqlCommand cmd = conn.CreateCommand()) { cmd.CommandText =”select * from T_Student where Age<18”; using(SqlDataReader reader=cmd.ExecuteReader() { while(reader.Read()) { string name=reader.GetString(1);//獲得第一列列的值 int age=reader.GetIn32(2); //獲得第2列列的值 Console.WriteLine(name); Console.WriteLine(age.ToString()); } } } }
其中Read方法返回bool類型,查詢結(jié)果是放到數(shù)據(jù)庫中,沒有放到客戶端。初始指針指向第一條數(shù)據(jù)之前,每調(diào)用一次Reader指針下移一條,只要沒有移到最后一條之后,就直接返回true。reader的GetString\GetInt32等方法只接受整數(shù)參數(shù),也就是序號,用GetOrdinal方法根據(jù)列名動態(tài)得到序號。
0列 |
第一列 |
第二列 |
第三列 |
Id |
Name |
Age |
Hobby |
1 |
XXX |
18 |
勾搭妹子 |
2 |
王旭 |
30 |
勾搭妹子 |
圖 1 數(shù)據(jù)庫T_Student表
為了避免數(shù)據(jù)庫注入漏洞,微軟設(shè)置有查詢參數(shù),舉例如下:
cmd.CommandText =”select * from T_Student where Age<@Age”;
cmd.Parameters.Add(new SqlParameter(“@Age”,19));
這里把@Age設(shè)置為查詢參數(shù),但是@參數(shù)不能用了替換表名、字段名、select之類的關(guān)鍵字等。
SqlDataReader是和連接相關(guān)的,SqlDataReader中的查詢結(jié)果并不是放在程序中的,而是放在數(shù)據(jù)庫服務(wù)器中,SqlDataReader只是相當(dāng)于一個游標(biāo),指到哪里讀到哪里。
ADO.NET提供了數(shù)據(jù)集機(jī)制,DataSet,存在本地內(nèi)存,其包含若干DataTable,DataTable包含若干行DataRow。使用方法:
DataSet dataset=new DataSet(); SqlDataAdapter adapter=new SqlDataAdapter(cmd); adapter.Fill(dataset);
SqlDataAdapter是一個幫我們把SqlCommand查詢結(jié)果填充到DataSet中的類,DataSet相當(dāng)于本地的list集合(小數(shù)據(jù)庫)。遍歷方法如下:
DataTable table=dataset.Tables[0];//一般情況下只有一個Tables,當(dāng)同時執(zhí)行多個select語句時有多個Tables。 DataRowCollection rows=table.Rows; for(int i=0;i<rows.Count;i++) { DataRow row=rows[i]; int age=(int)row[“Age”];//遍歷年齡 }
基本上所有的步驟都是:打開鏈接--創(chuàng)建命令--執(zhí)行--處理執(zhí)行結(jié)果。所以可以寫個公共類自己用,避免重復(fù)代碼,詳細(xì)代碼如下:
public static class SqlHelper { public static readonly string connstr = ConfigurationManager.ConnectionStrings["connstr"].ConnectionString; public static SqlConnection OpenConnection()//建立連接 { SqlConnection conn = new SqlConnection(connstr); conn.Open(); return conn; } public static int ExecuteNonQuery(string cmdText, params SqlParameter[] parameters)//注意看有使用長度可變參數(shù)進(jìn)行了簡化 { using (SqlConnection conn = new SqlConnection(connstr)) { conn.Open(); return ExecuteNonQuery(conn, cmdText, parameters); } } public static object ExecuteScalar(string cmdText, params SqlParameter[] parameters) { using (SqlConnection conn = new SqlConnection(connstr)) { conn.Open(); return ExecuteScalar(conn, cmdText, parameters); } } public static DataTable ExecuteDataTable(string cmdText, params SqlParameter[] parameters) { using (SqlConnection conn = new SqlConnection(connstr)) { conn.Open(); return ExecuteDataTable(conn, cmdText, parameters); } } public static int ExecuteNonQuery(SqlConnection conn,string cmdText, params SqlParameter[] parameters) { using (SqlCommand cmd = conn.CreateCommand()) { cmd.CommandText = cmdText; cmd.Parameters.AddRange(parameters); return cmd.ExecuteNonQuery();//返回執(zhí)行了多少行 } } public static object ExecuteScalar(SqlConnection conn, string cmdText, params SqlParameter[] parameters) { using (SqlCommand cmd = conn.CreateCommand()) { cmd.CommandText = cmdText; cmd.Parameters.AddRange(parameters); return cmd.ExecuteScalar(); } } public static DataTable ExecuteDataTable(SqlConnection conn, string cmdText, params SqlParameter[] parameters) { using (SqlCommand cmd = conn.CreateCommand()) { cmd.CommandText = cmdText; cmd.Parameters.AddRange(parameters); using (SqlDataAdapter adapter = new SqlDataAdapter(cmd)) { DataTable dt = new DataTable(); adapter.Fill(dt); return dt; } } } public static object ToDBValue(this object value) { return value == null ? DBNull.Value : value; } public static object FromDBValue(this object dbValue) { return dbValue == DBNull.Value ? null : dbValue; } }
封裝方法的原則:把不變的放到方法里,把變化的放到參數(shù)里,SqlHelper類里返回值是一行一列的用ExecuteScaler,ExecuteNonQuery一般用來執(zhí)行Update\Delete\Insert語句,ExecuteDataTable只用來執(zhí)行查詢結(jié)果比較少的sql,返回值是DataTable。
在數(shù)據(jù)庫中NULL和“”不一樣,NULL和0也不一樣。數(shù)據(jù)庫中NULL表示不“知道”。假如一個表中有個可空字段Name,如果有幾個實例Name為NULL,
select * from T_Student where Name=NULL是查不到任何數(shù)據(jù)的。
select * from T_Student where Name is NULL可以查到所有Name填NULL的數(shù)據(jù)。
需求:如果沒輸入姓名,則姓名應(yīng)該為NULL,如果沒輸入年齡,則年齡應(yīng)該為NULL。
問題:在SqlParameter如果參數(shù)值為null,則表示沒有提供參數(shù)的值,會報錯。
解決方法:.NET提供DBNull.Value用來表示數(shù)據(jù)庫中的NULL。以為DBNull.Value是object類型。所以需要這樣用:
object objName; string name=tbName.Text; if(name.Length<0) { objName=DBNull.Value; }else { objName=name; }
接著SqlParameter參數(shù)改為objName。
同時讀取數(shù)據(jù)庫時,存在Null,返回給.NET的值也是DBNull.Value。所以讀取后還要判斷后賦值,用法如下:
if(row[“Name”]==DBNull.Value) { name=null; } else { name=(string)row[“Name”]; }
但是也有個問題,如果是int類型,則不能為null,就該定義的時候用int? age。
必須嚴(yán)格區(qū)分0,NULL和“”,否則出現(xiàn)問題很難查到。
附帶上次講的SqlHelper里的兩個函數(shù),就是對上面兩個用法的封裝,可以直接用在SqlParameter參數(shù)中。
可空數(shù)據(jù)輸入數(shù)據(jù)庫時用
public static object ToDBValue(this object value) { return value == null ? DBNull.Value : value; }
輸出時用
public static object FromDBValue(this object dbValue) { return dbValue == DBNull.Value ? null : dbValue; }
這個主要是用在SqlParameter中,實現(xiàn)可空數(shù)據(jù)的輸入輸出。
以上內(nèi)容是關(guān)于本文給大家介紹的C#連接數(shù)據(jù)庫的方法,希望大家喜歡。
欄 目:C#教程
下一篇:分享WCF聊天程序--WCFChat實現(xiàn)代碼
本文標(biāo)題:C#連接數(shù)據(jù)庫的方法
本文地址:http://mengdiqiu.com.cn/a1/C_jiaocheng/6873.html
您可能感興趣的文章
- 01-10C#通過反射獲取當(dāng)前工程中所有窗體并打開的方法
- 01-10關(guān)于ASP網(wǎng)頁無法打開的解決方案
- 01-10WinForm限制窗體不能移到屏幕外的方法
- 01-10WinForm繪制圓角的方法
- 01-10C#停止線程的方法
- 01-10WinForm實現(xiàn)仿視頻 器左下角滾動新聞效果的方法
- 01-10C#通過重寫Panel改變邊框顏色與寬度的方法
- 01-10C#實現(xiàn)清空回收站的方法
- 01-10C#實現(xiàn)讀取注冊表監(jiān)控當(dāng)前操作系統(tǒng)已安裝軟件變化的方法
- 01-10C#實現(xiàn)多線程下載文件的方法


閱讀排行
本欄相關(guān)
- 01-10C#通過反射獲取當(dāng)前工程中所有窗體并
- 01-10關(guān)于ASP網(wǎng)頁無法打開的解決方案
- 01-10WinForm限制窗體不能移到屏幕外的方法
- 01-10WinForm繪制圓角的方法
- 01-10C#實現(xiàn)txt定位指定行完整實例
- 01-10WinForm實現(xiàn)仿視頻 器左下角滾動新
- 01-10C#停止線程的方法
- 01-10C#實現(xiàn)清空回收站的方法
- 01-10C#通過重寫Panel改變邊框顏色與寬度的
- 01-10C#實現(xiàn)讀取注冊表監(jiān)控當(dāng)前操作系統(tǒng)已
隨機(jī)閱讀
- 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 01-10delphi制作wav文件的方法
- 04-02jquery與jsp,用jquery
- 01-11ajax實現(xiàn)頁面的局部加載
- 08-05DEDE織夢data目錄下的sessions文件夾有什
- 01-10使用C語言求解撲克牌的順子及n個骰子
- 01-10C#中split用法實例總結(jié)
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 08-05織夢dedecms什么時候用欄目交叉功能?