CSharp 數據操作系列 - 2. ADO.NET操作

2020-12-19 程式設計師小高學習筆記

0.前言

在上一篇中初略的介紹了一下SQL的基本寫法,這一篇開始我們正式步入C#操作資料庫的範圍。通過這一系列的內容,我想大家能對於資料庫交互有了一定的認識和基礎。閒話不多說,先給大家介紹一個C#操作資料庫的方式。

1. ADO.NET的介紹

在ADO.NET出現之前,C#連接資料庫有很多種方式,各種框架琳琅滿目。用戶們飽受困擾,再加上亂七八糟的連接方式對語言的發展也是一種強有力的阻撓。所以微軟決定搞一套標準化出來,之後ADO.NET誕生了。

ADO.NET定義了一系列操作資料庫的接口和基類,而資料庫廠商只需要根據自己的實際情況開發對應的實現類就可以了。

2. 使用ADO.NET 操作需要的步驟

使用ADO.NET操作資料庫,先需要一個連接也就是 IDbConnection實例,然後使用IDbCommand執行,通過 IDataReader讀取數據。

先來簡單介紹一下上面提到的接口:

a.IDbConnection

表示一個與數據源的開放連接,並由訪問關係資料庫的.NET 數據提供程序實現,也就是說這只是一個接口,具體的實現得看具體的資料庫。

我們先看一下,具體的屬性和方法吧:

public string ConnectionString { get; set; }// 獲取或設置用於打開資料庫的連接字符串

public string Database { get; }//獲取當前連接或即將連接的資料庫名稱

public System.Data.ConnectionState State { get; }//獲取當前連接的狀態

public System.Data.IDbTransaction BeginTransaction ();//開啟一項資料庫事務

public void ChangeDatabase (string databaseName);//修改已打開連接的當前資料庫

public void Close ();//關閉當前連接

public System.Data.IDbCommand CreateCommand ();//創建並獲取與該連接關聯的命令對象

public void Open ();//開啟與資料庫的連接

b. IDbCommand

表示連接到數據源時執行的SQL命令,並由訪問關係資料庫的.NET數據提供程序實現。與IDbConnection一致,也是一個接口。

這個接口的屬性和方法如下:

public string CommandText { get; set; } //獲取或設置要對數據源運行的文本命令,也就是SQL語句

public int CommandTimeout { get; set; } //獲取或設置在終止嘗試執行命令並生成錯誤之前的等待時間

public System.Data.CommandType CommandType { get; set; }//指定或者獲取解釋CommandText屬性的方式

public System.Data.IDbConnection Connection { get; set; }//獲取或設置執行該命令的連接

public System.Data.IDataParameterCollection Parameters { get; }//獲取命令的參數化列表

public System.Data.IDbTransaction Transaction { get; set; }//獲取或設置該命令關聯的事務

public void Cancel ();//嘗試取消執行命令

public System.Data.IDbDataParameter CreateParameter ();//創建一個參數

public int ExecuteNonQuery ();//執行一個語句,並返回受影響的行數

public System.Data.IDataReader ExecuteReader ();//在Connect上執行CommandText,並返回一個IDataReader

public object ExecuteScalar ();//執行查詢,並返回第一行第一列,其他數據忽略

c. IDataReader

提供一種讀取結果集(通過對數據源執行命令獲取)的一個或多個只進流的方法,具體實現由訪問關係資料庫的.NET 數據提供程序實現。

這裡的只進流的意思類似於只讀流,也就是說它是一種單向的流,從資料庫傳向程序的流。

這個接口的屬性和方法如下:

public int Depth { get; }//獲取一個值,該值指示當前行的嵌套深度

public bool IsClosed { get; }// 獲取該讀取器的是否關閉

public int RecordsAffected { get; }//獲取由執行 SQL 語句而更改、插入或刪除的行數

public void Close ();//關閉IDataReader對象

public System.Data.DataTable GetSchemaTable ();//獲取一個描述該讀取器關聯的列元數據

public bool NextResult ();//顯示是否有下一行,如果有則在下次讀取的時候,讀取下一行的數據

public bool Read ();//與NextResult類似同時,IDataReader 繼承了接口 IDataRecord,也就是說IDataReader也能直接返回當前行的數據。

來,我們看看它從IDataRecord繼承了哪些吧(也就是IDataRecord有的屬性和方法)。

public int FieldCount { get; }//獲取當前行中的列數

public object this[int i] { get; }//獲取位於指定索引處的列

public object this[string name] { get; }//獲取具有指定名稱的列

public System.Data.IDataReader GetData (int i);//獲取指定列序號的DataReader

public Type GetFieldType (int i);//獲取對應於會從 Type 返回的 Object 類型的 GetValue(Int32) 信息

public string GetDataTypeName (int i);//獲取指定欄位的數據類型信息

public string GetName (int i);//獲取要查找的欄位的名稱

public int GetOrdinal (string name);//返回命名欄位的索引

public bool GetBoolean (int i);//作為布爾值獲取指定列的值

public byte GetByte (int i);//獲取指定列的 8 位無符號整數值

public char GetChar (int i);//獲取指定列的字符值

public DateTime GetDateTime (int i);//獲取指定欄位的日期和時間數據值

public decimal GetDecimal (int i);//獲取指定欄位的數值

public double GetDouble (int i);//獲取指定欄位的雙精度浮點數

public float GetFloat (int i);//獲取指定欄位的單精度浮點數

public Guid GetGuid (int i);//獲取指定欄位的GUID值

public short GetInt16 (int i);//獲取指定欄位的 16 位帶符號整數值

public long GetInt64 (int i);//獲取指定欄位的 64 位帶符號整數值

public string GetString (int i);//獲取指定欄位的字符串值

public object GetValue (int i);//返回指定欄位的值

public int GetValues (object[] values);// 將當前記錄的值按順序填充到數組中,並返回實際的數目

public bool IsDBNull (int i);//返回指定欄位是否設置為 null

特別補充說明

ConnectionState 是一個枚舉狀態,表示數據連接狀態,其屬性值如下:

CommandType 用來指定如何解釋命令字符串,屬性值如下:

3. 如何使用ADO.NET操作資料庫

以SQLServer為例,創建一個Connection:

using System.Data;

using System.Data.SqlClient;//Sql Server的命名空間

string connectStr = "";

IDbConnection connection = new SqlConnection(connectStr);

在.NET Framework中,以上代碼是正確的,因為.NET Framework內置了SQL Server的數據訪問程序,也就是數據驅動。但是在.NET Core中,需要為項目添加如下包的引用:

System.Data.SqlClient

這裡簡單介紹一下如何使用Visual Studio安裝包:

如圖所示,在【工具】->【NuGet 包管理器】下找到 管理解決方案的NuGet程序包,點擊。然後會出現類似於下圖:

然後點擊瀏覽,輸入:System.Data.SqlClient

選中第一項,然後在右側勾選要添加包的項目,然後點擊安裝。

OK,現在假設你們都已經安裝好了。然後繼續下一步操作:

執行一個查詢語句:

select name from demo;

創建一個Command:

這時候創建Command有這樣幾種方式:

IDbCommand command = connection.CreateCommand();// 通過 connection創建一個命令

IDbCommand command = new SqlCommand();//簡單創建一個命令對象

IDbCommand command = new SqlCommand(sql,connection);//在初始化的時候,指定要執行的SQL和連接的Connection

如果在創建Command的時候,沒有指定連接和要執行的SQL語句,那麼必須在獲取Reader之前,手動設置。

現在獲取一個Reader:

IDataReader reader = command.ExecuteReader();

如果只是想執行SQL,不關心返回內容的話,可以調用以下方法:

int lines = command.ExecuteNonQuery();// 獲取受影響的行數該方法適合於SQL是DML類型的SQL語句或者增刪改的SQL語句。

如果是查詢語句,則需要獲取Reader,然後通過Reader獲取對應的值。

4. 實踐

在大概講解了SQL,我們通過實踐練習把之前了解到的內容串聯起來。

a.創建一個表

var connectStr = "";

var sql = @"create table demo( [key] int identity primary key, [name] varchar(20))";

IDbConnection connection = new SqlConnection(connectStr);

IDbCommand command = connection.CreateCommand();

connection.Open();//開啟連結

command.CommandText = sql;//賦值sql

var result = command.ExecuteNonQuery();//獲取返回的int值,是-1

connection.Close();//用完了記得把連結關閉對於

ExcuteNonQuery的返回值,微軟在官方文檔中給出了這樣的描述:

對於 UPDATE、INSERT 和 DELETE 語句,返回值為該命令所影響的行數。 對於所有其他類型的語句,返回值是 -1。

所以這裡的返回值是-1。

b.添加一條數據

與創建表類似,區別在於使用的SQL語句不同。在C#中,使用ADO.NET 向資料庫添加值,需要手動拼接SQL語句來操作。

代碼如下:(假設使用在上一個示例裡創建的表)

拼接SQL:

var value1 = "測試";

var sql = @$"insert into demo(name) values('{value1}');";

//====或者

var sql = string.Format("insert into demo(name) values('{0}');", "測試");

注意SQL語句拼接過程中的單引號,這在SQL中表示中間是字符串。SQL有很強的將字符串轉換成對應欄位類型的能力,所以可以統一傳給資料庫字符串。

執行SQL:

var connectStr = "";

IDbConnection connection = new SqlConnection(connectStr);

IDbCommand command = connection.CreateCommand();

connection.Open();

command.CommandText = sql;

var result = command.ExecuteNonQuery();

connection.Close();

這次如果沒有執行錯誤的話,會返回一個1。

c.修改記錄

例如修改demo裡name為測試的數據,將其name修改為demo:

var connectStr = "";

var sql = "update demo set name = 'demo' where name = 『測試』";

IDbConnection connection = new SqlConnection(connectStr);

IDbCommand command = connection.CreateCommand();

connection.Open();

command.CommandText = sql;

var result = command.ExecuteNonQuery();

Console.WriteLine(result);

connection.Close();

其中result表示SQL影響的表中數據行數。

d. 刪除記錄

var sql = "delete table demo where name = 『測試』";

IDbConnection connection = new SqlConnection(connectStr);

IDbCommand command = connection.CreateCommand();

connection.Open();

command.CommandText = sql;

var result = command.ExecuteNonQuery();

Console.WriteLine(result);

connection.Close();

e. 查詢

這裡就先容我賣個關子,不過大家可以自己試試ADO.NET的查詢

5. 說明

在第四小節裡提到了連接字符串,對於C#來說,不同資料庫應當有不同的連接字符串。因為這是C#連接資料庫的一種指令或者是密鑰。

簡單介紹一下連接字符串,它是用分號隔開的鍵值對列表。格式如下:

keyword1=value; keyword2=value;

以下是一個標準的SQL Server連接字符串:

Persist Security Info=False;User ID=*****;Password=*****;Initial Catalog=AdventureWorks;Server=MySqlServer

其中:

Persist Security Info=False 表示使用帳戶密碼連接資料庫User ID 表示用戶名Password 表示密碼Initial Catalog=AdventureWorks 表示連接的資料庫是 AdventureWorks ,可根據自己需要修改Server=MySqlServer 表示資料庫在 MySqlServer 這個伺服器上,可以是IP位址或者域名等之所以留下了查詢沒有說,因為在ADO.NET中還有一種更棒的方式操作資料庫。這就是下篇內容要講的。如果有需要的小夥伴,別忘了關注評論哈。

相關焦點

  • C Sharp 數據操作系列 - 1. SQL基礎操作
    這一篇我們將繼續為C#數據操作的基礎填上一個空白-SQL語句。SQL(Structured Query Language,結構化查詢語言)是一種特定的程式語言,用於管理資料庫系統,操作數據甚至編寫一些程序。
  • 在Stata中編寫估計命令:編寫C語言插件
    完整地讀取Stata ado文件,並且在執行主要ado程序行之前加載每個ado程序,Mata函數或插件句柄。所以第10行實際上是在第6行之前執行的。 插件的句柄名稱,本例中的hello,必須與主要ado程序的名稱,本例中的myhello以及此.ado文件中定義的任何其他ado程序不同。 Code block 2中的hello.c的代碼。
  • c#.net多線程編程教學(3):線程同步
    正在閱讀:c#.net多線程編程教學(3):線程同步c#.net多線程編程教學(3):線程同步2005-07-07 10:44出處:作者:c-sharpcorner  考慮一種我們經常遇到的情況:有一些全局變量和共享的類變量,我們需要從不同的線程來更新它們,可以通過使用System.Threading.Interlocked類完成這樣的任務,它提供了原子的,非模塊化的整數更新操作。  還有你可以使用System.Threading.Monitor類鎖定對象的方法的一段代碼,使其暫時不能被別的線程訪問。
  • 傾向匹配得分教程(附PSM操作應用、平衡性檢驗、共同取值範圍、​核密度函數圖)
    計量百科·資源·乾貨:本文主要包括傾向匹配得分命令簡介、語法格式、傾向匹配得分操作步驟 思路,涉及傾向匹配得分應用、平衡性檢驗、共同取值範圍檢驗、核密度函數圖等內容。以下是最受歡迎的模塊(主要有如下幾個外部命令)psmatch2.adopscore.adonnmatch.adopsmatch2.ado was developed by Leuven and Sianesi (2003) and pscore.ado by Becker and Ichino (2002).
  • 編程去除背景綠幕摳圖,基於.NET+OpenCVSharp
    FindContoursAsArray(matInternalHollow, RetrievalModes.External, ContourApproximationModes.ApproxNone).Select(c => new { contour = c, Area = Cv2.ContourArea(c) })
  • Stata程序:10 分鐘快樂編寫 ado 文件
    = " `a'3.3 使用 ado 文件計算階乘在 3.2 中,如果我們需要多次計算階乘必須不斷改變 k 值並重複執行 dofile 中的命令,但是我們可以通過使用  ado 文件  簡化這些步驟。我們做了什麼調整呢?
  • 經典.NET三層+ASP.NET MVC 5+ADO.NET實現顯示、添加和刪除數據
    通過DBHelper.cs類庫使用SQL語句操作資料庫,數據訪問層使用DAL表示。業務邏輯層:主要用於處理複雜的業務邏輯,不能與資料庫打交道,該是表現層與數據訪問的中間層。不管是向資料庫保存數據還是返回資料庫中的數據,都必須經過業務邏輯層的處理。業務邏輯層使用BLL表示。
  • NET開發-在DBHelper中封裝ADO.NET對象,並調用執行添加數據功能
    編寫C#代碼在.NET應用程式中,對於經常性的資料庫操作,一般都會將與資料庫相關的操作封裝到DBHelper類庫中,幫助資料庫的操作。下面在Visual Studio的解決方案中添加一個類庫文件:1.2. 調用DBHelper類庫對於封裝好的DBHelper類庫,就可以在ASP.NET WebForm應用程式中調用來操作SQL Server資料庫中了。
  • 傾向匹配得分教程【pscore、psmatch2、官方命令Teffects操作及應用】
    以下是最受歡迎的模塊(主要有如下幾個外部命令)psmatch2.adopscore.adonnmatch.ado上述主要介紹了如何獲得PSM相關的命令,本文主要介紹如何使用pscore、psmatch2以及Stata官方的PSM命令Teffects。
  • Without further ado是什麼意思?
    Without further ado是什麼意思?把without further ado說成英語Without further ado是用來做「知道中文什麼意思」訓練,還是做把英語學成英語能力訓練?比如:without further ado,我們就是用它來訓練自己在學過的英語之間「融會貫通」的能力的。看下面(學過)的英語,記住下面(學過)的英語:1. Okay.I got you.
  • suest - 支持面板數據的似無相關檢驗
    >  Stata 連享會: 知乎 | 簡書 | 碼雲連享會最受歡迎的課🍎2021Stata 寒假班🎦2021年1.25—
  • C語言-數據結構
    計算機的算法與數據結構密切相關,算法無不依賴於數據結構,而數據結構也關係到算法的效率,直接決定了一個程序的好壞。什麼是數據結構數據結構,直白地理解,就是研究數據的存儲方式。我們知道,數據存儲只有一個目的,即為了方便後期對數據的再利用,就如同我們使用數組存儲 {1,2,3,4,5} 是為了後期取得它們的加和值,無緣由的數據存儲行為是對存儲空間的不負責任。因此,數據在計算機存儲空間的存放,決不是胡亂的,這就要求我們選擇一種好的方式來存儲數據,而這也是數據結構的核心內容。
  • C Sharp 基礎知識系列- 2 字符串
    為什麼會如此呢,究其原因是String在內存中以類似數組的形式存儲字符數據。同時,String 還有一個非常有意思的特點: 字符串在一次聲明後,程序會記憶當前已聲明的字符串,以備下次使用時不用重新劃分內存。
  • NET開發-使用C#+ADO.NET在SQL Server表中添加、更新和刪除數據
    2.SqlCommand對象2.1. ExecuteNonQuery()方法的使用2.1.1. 插入數據使用ADO.NET在BW_TestDB資料庫中BW_Student表中插入一條數據。ADO.NET插入數據這一段完整的使用C#操作資料庫的代碼,非常的簡單,微軟將所有的複雜操作都簡單化了,我們只需要學會怎麼使用就可以了。
  • R語言 | 數據框data.frame操作一網打盡
    創建數據框2. 行名列名等屬性3. 獲取元素(遍歷)4. 修改(增刪改、轉置、melt)5. 連接數據框、拆分數據框6. 數據框的計算,按某列求平均值 (數據透視表)數據框(data.frame)在R中使用的十分廣泛。只要你用read.table輸入數據,基本都是data.frame類別的數據。
  • CSharp 基礎知識系列-IO篇 流的操作
    前言繼續之前的C# IO流,在前幾篇小短片中我們大概看了下C# 的基礎IO也對文件、目錄和路徑的操作有了一定的了解。這一篇開始,給大家演示一下流的各種操作。以文件流為例,一起來看看如何操作吧。2. 使用流適配器普通的流讀取和寫入都是使用字節數組,這在實際開發中非常不方便,所以C#又在流的基礎上開發了流適配器。C#中流適配器是指XXXReader或者XXXWriter,這種類在初始化的時候傳入一個流作為操作對象,然後對這個流進行一定的封裝,簡化了其操作方法。
  • 「無伺服器架構」動手操作Knative -第2部分
    2 Running最後,我們可以創建Knative服務,並使用訂閱伺服器中的訂閱將其連結到subscriber.yaml文件:apiVersion: serving.knative.dev/v1alpha1 kind: Servicemetadata: name: message-dumper-csharp
  • C Sharp 基礎知識系列- 16 開發工具篇
    首先需要明確一個概念,C#是一門程式語言,.net是一個CLR,即公共語言運行庫。這部分概念比較抽象,不過我這麼說大家可能會理解裡面的關係了:C#是.net支持的一門語言,於此同時.net還支持F#,Visual C++等。也就是說,.net是一個平臺,而C#是運行在這個平臺上的語言。