主頁 > .NET開發 > C#中SQLite的使用及工具類

C#中SQLite的使用及工具類

2021-04-15 07:56:37 .NET開發

目錄
  • SQLite簡介
    • 存盤類
    • 親和型別
  • 參考System.Data.SQLite.dll
    • 軟體包分類
    • 使用本機庫預加載
    • 常用部署包
  • 工具類
  • 參考資料

SQLite簡介

SQLite是一款輕型的資料庫,一個資料庫就是一個檔案,詳細介紹參考官網:https://www.sqlite.org/index.html

SQLite 資料型別是一個用來指定任何物件的資料型別的屬性,SQLite 中的每一列,每個變數和運算式都有相關的資料型別,
您可以在創建表的同時使用這些資料型別,SQLite 使用一個更普遍的動態型別系統,在 SQLite 中,值的資料型別與值本身是相關的,而不是與它的容器相關,

SQLite資料與常見的MySQL、SQL等的資料庫不一樣,它是動態型別資料庫,每個值在資料庫占的存盤空間根據值的大小確定,使用時需要注意資料型別的問題,

存盤類

每個存盤在 SQLite 資料庫中的值都具有以下存盤類之一:

存盤類 描述
NULL 值是一個 NULL 值,
INTEGER 值是一個帶符號的整數,根據值的大小存盤在 1、2、3、4、6 或 8 位元組中,
REAL 值是一個浮點值,存盤為 8 位元組的 IEEE 浮點數字,
TEXT 值是一個文本字串,使用資料庫編碼(UTF-8、UTF-16BE 或 UTF-16LE)存盤,
BLOB 值是一個 blob 資料,完全根據它的輸入存盤,

親和型別

SQLite支持列的親和型別概念,任何列仍然可以存盤任何型別的資料,當資料插入時該欄位的資料將會優先采用親和型別作為該值的存盤方式
創建 SQLite3 表時可使用的各種資料型別名稱及相應的親和型別,如下:

資料型別 親和型別
INT
INTEGER
TINYINT
SMALLINT
MEDIUMINT
BIGINT
UNSIGNED BIG INT
INT2
INT8
INTEGER:對于親緣型別為INTEGER的欄位,其規則等同于NUMERIC,唯一差別是在執行CAST運算式時,
CHARACTER(20)
VARCHAR(255)
VARYING CHARACTER(255)
NCHAR(55)
NATIVE CHARACTER(70)
NVARCHAR(100)
TEXT
CLOB
TEXT:數值型資料在被插入之前,需要先被轉換為文本格式,之后再插入到目標欄位中,
BLOB
no datatype specified
NONE:不做任何的轉換,直接以該資料所屬的資料型別進行存盤,
REAL
DOUBLE
DOUBLE PRECISION
FLOAT
REAL:其規則基本等同于NUMERIC,唯一的差別是不會將"30000.0"這樣的文本資料轉換為INTEGER存盤方式,
NUMERIC
DECIMAL(10,5)
BOOLEAN
DATE
DATETIME
NUMERIC
當文本資料被插入到親緣性為NUMERIC的欄位中時:
如果轉換操作不會導致資料資訊丟失以及完全可逆,那么SQLite就會將該文本資料轉換為INTEGER或REAL型別的資料;
如果轉換失敗,SQLite仍會以TEXT方式存盤該資料,

對于NULL或BLOB型別的新資料,SQLite將不做任何轉換,直接以NULL或BLOB的方式存盤該資料,

注:對于浮點格式的常量文本,如"30000.0",如果該值可以轉換為INTEGER同時又不會丟失數值資訊,那么SQLite就會將其轉換為INTEGER的存盤方式,

參考System.Data.SQLite.dll

在C#中使用SQLite資料庫需要參考System.Data.SQLite.dll,下載鏈接:http://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki

注:System.Data.SQLite是SQLite的ADO.NET提供程式,兩者是兩個不同的開源專案,現在System.Data.SQLite的開發和維護作業大部分由SQLite開發團隊執行,

System.Data.SQLite的下載頁面選項太多,一般人進來都不清楚要下載那些內容,下面對下載界面中的軟體包做一個簡單介紹,

軟體包分類

下載內容按型別分為安裝包非靜態連接的二進制包靜態連接的二進制包三種,區別如下:

  • 安裝程式包僅用于在開發人員計算機上安裝,然后僅在需要VisualStudio的設計時組件時安裝,不建議安裝在客戶機器上(理論上也可以),
  • 安裝包會安裝相關的動態庫到系統內,并注冊到GAC(Global Assembly Cache),
  • 二進制軟體包旨在供開發人員使用,以便獲得開發所需的匯編二進制檔案,并通過XCOPY部署將其應用程式部署到客戶機上
  • 兩種二進制包的區別在于非托管部分的連接方式不同,非靜態連接的二進制包在使用時需要VC運行時庫的支持

注:如果所有目標機器已經安裝了VisualC++運行時,或者可以容易地部署,則應該避免“靜態”包

每個型別都按.NET版本分成了若干小組,每個.NET版本又分為32位64位兩組:

  • 支持的.NET版本有 2.0 SP2 、 3.5 SP2 、4.0 、 4.5 、 4.5.1 、4.6
  • 選用32位還是64位是根據使用系統來決定的,如開發時是64位(使用64位dll)系統而發布后運行在32位(使用32位dll)系統上,

注:雖然.NET高版本兼容低版本,但強烈建議選擇與目標.NET Framework版本匹配的包

在每個.NET版本-位數分組中都有2個檔案包,一個帶有“bundle”字樣,另一個沒有:

  • 帶有“bundle”字樣的表示動態庫是按混合模式編譯的,在使用的時候只需要System.Data.SQLite.dll就可以了,
  • 不帶“bundle”的則是將非托管部分和托管部分分別編譯System.Data.SQLite.dll不能獨立使用,還需要有SQLite.Interop.dll才能使用

注:除非認為絕對必要,否則應避免使用“bundle”包

根據上面的介紹,如果開發機器和客戶機器可能具有不同的處理器體系結構,則可能需要一個以上的二進制程式包,

使用本機庫預加載

本機庫預加載功能從1.0.80.0版本開始可用,并且默認情況下已啟用,能夠自動適應當前系統的位數,為了利用此功能,必須將單獨的托管程式集和互操作程式集與XCOPY部署一起使用(混合模式程式集、安裝軟體包部署不支持此功能),
使用本機庫預加載功能時,應用程式部署看起來如下( bin 表示將在目標計算機上部署應用程式二進制檔案的目錄):

  • bin \ App.exe(可選,僅受管應用程式可執行程式集)
  • bin \ App.dll(可選,僅托管應用程式庫程式集)
  • bin \ System.Data.SQLite.dll(必需,僅受管核心程式集)
  • bin \ System.Data.SQLite.Linq.dll(可選,僅托管LINQ程式集)
  • bin \ System.Data.SQLite.EF6.dll(可選,僅托管EF6程式集)
  • bin \ x86 \ SQLite.Interop.dll(必需,x86本機互操作程式集)
  • bin \ x64 \ SQLite.Interop.dll(必需,x64本機互操作程式集)

啟用本機庫預加載功能并顯示上面的應用程式部署后,System.Data.SQLite僅限托管程式集將嘗試自動檢測當前行程的處理器體系結構并預加載適當的本機庫,此時不用考慮客戶機器的是64位還是32位

常用部署包

我把.NET的4.0 、4.5版本對應的軟體包按本機庫預加載功能的要求重新組裝,使用時直接復制到Debug目錄下即可:

  • sqlite-netFx45-binary-Win32-x64-2012-1.0.113.0.zip 提取碼: r4yy
  • sqlite-netFx40-binary-Win32-x64-2010-1.0.113.0.zip 提取碼: j88h
  • sqlite-netFx45-static-binary-Win32-x64-2012-1.0.113.0.zip 提取碼: 33kp
  • sqlite-netFx40-static-binary-Win32-x64-2010-1.0.113.0.zip 提取碼: iqr2

注:官方建議不使用靜態的二進制包,我個人則喜歡用靜態的二進制包,這樣就不用考慮客戶機器上是否安裝有對應的VC運行時庫了,

工具類

工具類大部分內容來自c# Sqlite幫助類,考慮到SQLite是一個資料庫一個檔案、一個專案可能需要多個資料庫,我將工具類改為通過物件實體操作資料庫并提供一個靜態的物件實體字典,
工具類代碼如下:

public class SQLiteHelper
{
    /// <summary>
    /// 資料庫串列
    /// </summary>
    public static Dictionary<string, SQLiteHelper> DataBaceList = new Dictionary<string, SQLiteHelper>();

    /// <summary>
    /// 建構式
    /// </summary>
    /// <param name="filename">資料庫檔案名</param>
    public SQLiteHelper(string filename=null) 
    {
        DataSource = filename;                     
    }

    /// <summary>
    /// 資料庫地址
    /// </summary>
    public string DataSource { get; set; }        

    /// <summary>
    /// 創建資料庫,如果資料庫檔案存在則忽略此操作
    /// </summary>
    public void CreateDataBase() 
    {
        string path = Path.GetDirectoryName(DataSource);
        if ((!string.IsNullOrWhiteSpace(path)) && (!Directory.Exists(path))) Directory.CreateDirectory(path);
        if (!File.Exists(DataSource)) SQLiteConnection.CreateFile(DataSource);          
    }



    /// <summary>
    /// 獲得連接物件
    /// </summary>
    /// <returns>SQLiteConnection</returns>       
    public SQLiteConnection GetSQLiteConnection()
    {
        string connStr =string.Format("Data Source={0}", DataSource);            
        var con = new SQLiteConnection(connStr);
        return con;
    }

    /// <summary>
    /// 準備操作命令引數
    /// </summary>
    /// <param name="cmd">SQLiteCommand</param>
    /// <param name="conn">SQLiteConnection</param>
    /// <param name="cmdText">Sql命令文本</param>
    /// <param name="data">引數陣列</param>
    private static void PrepareCommand(SQLiteCommand cmd, SQLiteConnection conn, string cmdText, Dictionary<String, String> data)
    {
        if (conn.State != ConnectionState.Open)
            conn.Open();
        cmd.Parameters.Clear();
        cmd.Connection = conn;
        cmd.CommandText = cmdText;
        cmd.CommandType = CommandType.Text;
        cmd.CommandTimeout = 30;
        if (data != null && data.Count >= 1)
        {
            foreach (KeyValuePair<String, String> val in data)
            {
                cmd.Parameters.AddWithValue(val.Key, val.Value);
            }
        }
    }

    /// <summary>
    /// 查詢,回傳DataSet
    /// </summary>
    /// <param name="cmdText">Sql命令文本</param>
    /// <param name="data">引數陣列</param>
    /// <returns>DataSet</returns>
    public DataSet ExecuteDataset(string cmdText, Dictionary<string, string> data = https://www.cnblogs.com/timefiles/archive/2021/04/14/null)
    {
        var ds = new DataSet();
        using (SQLiteConnection connection = GetSQLiteConnection())
        {
            var command = new SQLiteCommand();
            PrepareCommand(command, connection, cmdText, data);
            var da = new SQLiteDataAdapter(command);
            da.Fill(ds);
        }
        return ds;
    }

    /// 
    /// 查詢,回傳DataTable
    /// 
    /// 
    /// 回傳一行資料
    /// 
    ///  0 && ds.Tables[0].Rows.Count > 0)
            return ds.Tables[0].Rows[0];
        return null;
    }

    /// 
    /// 執行資料庫操作
    /// 
    /// 
    /// 回傳SqlDataReader物件
    /// 
    /// 
    /// 回傳結果集中的第一行第一列,忽略其他行或列
    /// 
    /// 
    /// 分頁查詢
    /// 
    /// 

工具類使用方法如下:

static void Main(string[] args)
{
    SQLiteHelper testDb = new SQLiteHelper("test.db");
    SQLiteHelper.DataBaceList.Add("TEST", testDb);

    //建庫
    testDb.CreateDataBase();

    //建表            
    StringBuilder sbr = new StringBuilder();
    sbr.AppendLine("CREATE TABLE IF NOT EXISTS `test_table`(");
    sbr.AppendLine("`id` INTEGER PRIMARY KEY AUTOINCREMENT,");//自增id主鍵
    sbr.AppendLine("`name` VARCHAR(100) NOT NULL,");
    sbr.AppendLine("`password` VARCHAR(40) NOT NULL,");
    sbr.AppendLine("`create_time` datetime DEFAULT CURRENT_TIMESTAMP,");
    sbr.AppendLine("`update_time` datetime DEFAULT CURRENT_TIMESTAMP );");            
    sbr.AppendLine();

    sbr.AppendLine("CREATE TRIGGER  IF NOT EXISTS `trigger_test_table_update_time` ");//觸發器-自動更新update_time
    sbr.AppendLine("AFTER UPDATE ON `test_table` ");
    sbr.AppendLine("FOR EACH ROW ");
    sbr.AppendLine("BEGIN ");
    sbr.AppendLine("UPDATE `test_table` SET `update_time` = CURRENT_TIMESTAMP WHERE id = old.id; ");
    sbr.AppendLine("END;");

    string cmdText = sbr.ToString();
    int val = testDb.ExecuteNonQuery(cmdText);            
    Console.WriteLine("影響行數:" + val);

    //增
    sbr.Clear();
    sbr.Append("INSERT INTO test_table (name,password) VALUES ");
    sbr.Append("(11,111), ");
    sbr.Append("(12,222); ");
    cmdText = sbr.ToString();
    val = testDb.ExecuteNonQuery(cmdText);
    Console.WriteLine("影響行數:" + val);

    //刪
    sbr.Clear();
    sbr.Append("DELETE FROM test_table ");
    sbr.Append("WHERE id=1;");
    cmdText = sbr.ToString();
    val = testDb.ExecuteNonQuery(cmdText);
    Console.WriteLine("影響行數:" + val);

    //改
    sbr.Clear();
    sbr.Append("UPDATE test_table SET ");
    sbr.Append("name='13', ");
    sbr.Append("password='333' ");
    sbr.Append("WHERE id=@id;");
    cmdText = sbr.ToString();
    Dictionary<string, string> data = https://www.cnblogs.com/timefiles/archive/2021/04/14/new Dictionary();
    data.Add("@id", "2");           
    val = testDb.ExecuteNonQuery(cmdText, data);
    Console.WriteLine("影響行數:" + val);

    //查
    sbr.Clear();
    sbr.Append("SELECT name,password FROM test_table ");
    sbr.Append("WHERE id=@id;");
    cmdText = sbr.ToString();
    DataTable dt = testDb.ExecuteDataTable(cmdText, data);
    Console.WriteLine("結果行數:" + dt.Rows.Count);                                   

    //洗掉表
    sbr.Clear();
    sbr.Append("DROP TABLE test_table;");
    cmdText = sbr.ToString();
    val = SQLiteHelper.DataBaceList["TEST"].ExecuteNonQuery(cmdText);
    Console.WriteLine("影響行數:" + val);

    //重組資料庫
    SQLiteHelper.DataBaceList["TEST"].ResetDataBass();

    Console.ReadKey();
}

參考資料

  • c# Sqlite幫助類
  • 讓使用SQLite的.NET應用自適應32位/64位系統
  • System.Data.SQLite
  • sqlite3自增key設定(創建自增欄位)
  • Sqlite如何自動更新時間欄位

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/276136.html

標籤:.NET技术

上一篇:asp.net core 批量依賴注入服務

下一篇:AgileConfig - 輕量級配置中心1.2.0發布,全新的UI???

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • WebAPI簡介

    Web體系結構: 有三個核心:資源(resource),URL(統一資源識別符號)和表示 他們的關系是這樣的:一個資源由一個URL進行標識,HTTP客戶端使用URL定位資源,表示是從資源回傳資料,媒體型別是資源回傳的資料格式。 接下來我們說下HTTP. HTTP協議的系統是一種無狀態的方式,使用請求/ ......

    uj5u.com 2020-09-09 22:07:47 more
  • asp.net core 3.1 入口:Program.cs中的Main函式

    本文分析Program.cs 中Main()函式中代碼的運行順序分析asp.net core程式的啟動,重點不是剖析原始碼,而是理清程式開始時執行的順序。到呼叫了哪些實體,哪些法方。asp.net core 3.1 的程式入口在專案Program.cs檔案里,如下。ususing System; us ......

    uj5u.com 2020-09-09 22:07:49 more
  • asp.net網站作為websocket服務端的應用該如何寫

    最近被websocket的一個問題困擾了很久,有一個需求是在web網站中搭建websocket服務。客戶端通過網頁與服務器建立連接,然后服務器根據ip給客戶端網頁發送資訊。 其實,這個需求并不難,只是剛開始對websocket的內容不太了解。上網搜索了一下,有通過asp.net core 實作的、有 ......

    uj5u.com 2020-09-09 22:08:02 more
  • ASP.NET 開源匯入匯出庫Magicodes.IE Docker中使用

    Magicodes.IE在Docker中使用 更新歷史 2019.02.13 【Nuget】版本更新到2.0.2 【匯入】修復單列匯入的Bug,單元測驗“OneColumnImporter_Test”。問題見(https://github.com/dotnetcore/Magicodes.IE/is ......

    uj5u.com 2020-09-09 22:08:05 more
  • 在webform中使用ajax

    如果你用過Asp.net webform, 說明你也算是.NET 開發的老兵了。WEBform應該是2011 2013左右,當時還用visual studio 2005、 visual studio 2008。后來基本都用的是MVC。 如果是新開發的專案,估計沒人會用webform技術。但是有些舊版 ......

    uj5u.com 2020-09-09 22:08:50 more
  • iis添加asp.net網站,訪問提示:由于擴展配置問題而無法提供您請求的

    今天在iis服務器配置asp.net網站,遇到一個問題,記錄一下: 問題:由于擴展配置問題而無法提供您請求的頁面。如果該頁面是腳本,請添加處理程式。如果應下載檔案,請添加 MIME 映射。 WindowServer2012服務器,添加角色安裝完.netframework和iis之后,運行aspx頁面 ......

    uj5u.com 2020-09-09 22:10:00 more
  • WebAPI-處理架構

    帶著問題去思考,大家好! 問題1:HTTP請求和回傳相應的HTTP回應資訊之間發生了什么? 1:首先是最底層,托管層,位于WebAPI和底層HTTP堆疊之間 2:其次是 訊息處理程式管道層,這里比如日志和快取。OWIN的參考是將訊息處理程式管道的一些功能下移到堆疊下端的OWIN中間件了。 3:控制器處理 ......

    uj5u.com 2020-09-09 22:11:13 more
  • 微信門戶開發框架-使用指導說明書

    微信門戶應用管理系統,采用基于 MVC + Bootstrap + Ajax + Enterprise Library的技術路線,界面層采用Boostrap + Metronic組合的前端框架,資料訪問層支持Oracle、SQLServer、MySQL、PostgreSQL等資料庫。框架以MVC5,... ......

    uj5u.com 2020-09-09 22:15:18 more
  • WebAPI-HTTP編程模型

    帶著問題去思考,大家好!它是什么?它包含什么?它能干什么? 訊息 HTTP編程模型的核心就是訊息抽象,表示為:HttPRequestMessage,HttpResponseMessage.用于客戶端和服務端之間交換請求和回應訊息。 HttpMethod類包含了一組靜態屬性: private stat ......

    uj5u.com 2020-09-09 22:15:23 more
  • 部署WebApi隨筆

    一、跨域 NuGet參考Microsoft.AspNet.WebApi.Cors WebApiConfig.cs中配置: // Web API 配置和服務 config.EnableCors(new EnableCorsAttribute("*", "*", "*")); 二、清除默認回傳XML格式 ......

    uj5u.com 2020-09-09 22:15:48 more
最新发布
  • C#多執行緒學習(二) 如何操縱一個執行緒

    <a href="https://www.cnblogs.com/x-zhi/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2943582/20220801082530.png" alt="" /></...

    uj5u.com 2023-04-19 09:17:20 more
  • C#多執行緒學習(二) 如何操縱一個執行緒

    C#多執行緒學習(二) 如何操縱一個執行緒 執行緒學習第一篇:C#多執行緒學習(一) 多執行緒的相關概念 下面我們就動手來創建一個執行緒,使用Thread類創建執行緒時,只需提供執行緒入口即可。(執行緒入口使程式知道該讓這個執行緒干什么事) 在C#中,執行緒入口是通過ThreadStart代理(delegate)來提供的 ......

    uj5u.com 2023-04-19 09:16:49 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    <a href="https://www.cnblogs.com/huangxincheng/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/214741/20200614104537.png" alt="" /&g...

    uj5u.com 2023-04-18 08:39:04 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    一:背景 1. 講故事 前段時間協助訓練營里的一位朋友分析了一個程式卡死的問題,回過頭來看這個案例比較經典,這篇稍微整理一下供后來者少踩坑吧。 二:WinDbg 分析 1. 為什么會卡死 因為是表單程式,理所當然就是看主執行緒此時正在做什么? 可以用 ~0s ; k 看一下便知。 0:000> k # ......

    uj5u.com 2023-04-18 08:33:10 more
  • SignalR, No Connection with that ID,IIS

    <a href="https://www.cnblogs.com/smartstar/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/u36196.jpg" alt="" /></a>...

    uj5u.com 2023-03-30 17:21:52 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:15:33 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:13:31 more
  • C#遍歷指定檔案夾中所有檔案的3種方法

    <a href="https://www.cnblogs.com/xbhp/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/957602/20230310105611.png" alt="" /></a&...

    uj5u.com 2023-03-27 14:46:55 more
  • C#/VB.NET:如何將PDF轉為PDF/A

    <a href="https://www.cnblogs.com/Carina-baby/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2859233/20220427162558.png" alt="" />...

    uj5u.com 2023-03-27 14:46:35 more
  • 武裝你的WEBAPI-OData聚合查詢

    <a href="https://www.cnblogs.com/podolski/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/616093/20140323000327.png" alt="" /><...

    uj5u.com 2023-03-27 14:46:16 more