首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> ASP.NET 基礎

ASP.NET 整合 SQLite 完整實戰:ADO.NET Provider 安裝、連線字串、CRUD 操作與參數化查詢

     編輯:ASP.NET 基礎

環境準備:安裝 ADO.NET Provider

  1. 下載 System.Data.SQLite (ADO.NET 2.0/4.x) 官方安裝包:
    https://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki
  2. 執行安裝程式,勾選「Install into GAC」與「Register for Entity Framework」
  3. 專案右鍵 → 「管理 NuGet 套件」 → 搜尋 System.Data.SQLite → 安裝 System.Data.SQLite.Core (含原生二進位) 或 System.Data.SQLite (完整包)

連線字串配置

<connectionStrings>
  <!-- 檔案型資料庫,App_Data 目錄 -->
  <add name="SQLiteConn" 
       connectionString="Data Source=|DataDirectory|\AppData.db;Version=3;Foreign Keys=True;" 
       providerName="System.Data.SQLite" />
  
  <!-- 記憶體資料庫 (測試/快取用) -->
  <add name="SQLiteMemory" 
       connectionString="Data Source=:memory:;Version=3;" 
       providerName="System.Data.SQLite" />
</connectionStrings>

完整 CRUD 範例


using System;
using System.Data;
using System.Data.SQLite;
using System.Web.UI.WebControls;

public partial class _Default : System.Web.UI.Page
{
    private string ConnStr => ConfigurationManager.ConnectionStrings["SQLiteConn"].ConnectionString;

    protected void btnTest_Click(object sender, EventArgs e)
    {
        // 1. 建立資料庫檔案 (若不存在)
        string dbPath = Server.MapPath("~/App_Data/AppData.db");
        if (!File.Exists(dbPath))
        {
            SQLiteConnection.CreateFile(dbPath);
            InitializeSchema();
        }

        using (var conn = new SQLiteConnection(ConnStr))
        {
            conn.Open();
            Response.Write("✅ 開啟資料庫成功<br/>");

            // 2. 建立資料表
            ExecuteNonQuery(conn, @"
                CREATE TABLE IF NOT EXISTS Users (
                    UserID INTEGER PRIMARY KEY AUTOINCREMENT,
                    UserName TEXT NOT NULL,
                    UserPassword TEXT NOT NULL,
                    CreatedAt TEXT DEFAULT (datetime('now'))
                )");
            Response.Write("✅ 資料表就緒<br/>");

            // 3. 批次插入 (參數化)
            using (var txn = conn.BeginTransaction())
            {
                var cmd = conn.CreateCommand();
                cmd.CommandText = "INSERT INTO Users (UserName, UserPassword) VALUES (@name, @pwd)";
                var pName = cmd.CreateParameter(); pName.ParameterName = "@name";
                var pPwd = cmd.CreateParameter(); pPwd.ParameterName = "@pwd";
                cmd.Parameters.Add(pName); cmd.Parameters.Add(pPwd);

                for (int i = 1; i <= 100; i++)
                {
                    pName.Value = $"TestUser_{i}";
                    pPwd.Value = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                    cmd.ExecuteNonQuery();
                }
                txn.Commit();
            }
            Response.Write("✅ 批次插入 100 筆完成<br/>");

            // 4. 單筆查詢 (ExecuteScalar)
            string name = ExecuteScalar(conn, "SELECT UserName FROM Users WHERE UserID = 1")?.ToString();
            Response.Write($"✅ 單值查詢: {name}<br/>");

            // 5. 多筆查詢 (DataReader)
            Response.Write("<br/>📋 所有使用者:<br/>");
            using (var cmd = new SQLiteCommand("SELECT * FROM Users", conn))
            using (var reader = cmd.ExecuteReader())
            {
                while (reader.Read())
                {
                    Response.Write($"ID: {reader["UserID"]}, Name: {reader["UserName"]}, Pwd: {reader["UserPassword"]}<br/>");
                }
            }

            // 6. 更新
            ExecuteNonQuery(conn, "UPDATE Users SET UserPassword = 'updated_pwd' WHERE UserID = 1");
            Response.Write("✅ 更新完成<br/>");

            // 7. 刪除
            ExecuteNonQuery(conn, "DELETE FROM Users WHERE UserID > 50");
            Response.Write("✅ 刪除 ID>50 完成<br/>");
        }
    }

    private void InitializeSchema()
    {
        using (var conn = new SQLiteConnection(ConnStr))
        {
            conn.Open();
            ExecuteNonQuery(conn, @"
                CREATE TABLE IF NOT EXISTS Users (
                    UserID INTEGER PRIMARY KEY AUTOINCREMENT,
                    UserName TEXT NOT NULL UNIQUE,
                    UserPassword TEXT NOT NULL,
                    CreatedAt TEXT DEFAULT (datetime('now'))
                )");
        }
    }

    private int ExecuteNonQuery(SQLiteConnection conn, string sql, params SQLiteParameter[] parameters)
    {
        using (var cmd = conn.CreateCommand())
        {
            cmd.CommandText = sql;
            if (parameters != null) cmd.Parameters.AddRange(parameters);
            return cmd.ExecuteNonQuery();
        }
    }

    private object ExecuteScalar(SQLiteConnection conn, string sql, params SQLiteParameter[] parameters)
    {
        using (var cmd = conn.CreateCommand())
        {
            cmd.CommandText = sql;
            if (parameters != null) cmd.Parameters.AddRange(parameters);
            return cmd.ExecuteScalar();
        }
    }
}

關鍵 API 對照表

操作SQLite 類別/方法備註
建立資料庫檔案SQLiteConnection.CreateFile(path)僅建立空檔案,需 Open 後才能建表
開啟連線new SQLiteConnection(connStr).Open()支援連線池:Pooling=True;Max Pool Size=100
參數化查詢cmd.Parameters.AddWithValue("@p", val)防 SQL 注入、型別安全
交易conn.BeginTransaction()批次操作必須用交易,效能提升 10x+
單值查詢cmd.ExecuteScalar()回傳第一行第一欄
資料流讀取cmd.ExecuteReader()前向唯讀,低記憶體佔用
DataTable 填充new SQLiteDataAdapter(cmd).Fill(dt)適合小資料量綁定 GridView

SQLite 特有功能

1. JSON1 擴充 (內建)


// 儲存 JSON
cmd.CommandText = "INSERT INTO Logs (Data) VALUES (json(@json))";
cmd.Parameters.AddWithValue("@json", "{\"user\":123,\"action\":\"login\"}");

// 查詢 JSON 欄位
cmd.CommandText = "SELECT json_extract(Data, '$.user') FROM Logs";

2. 全文搜尋 FTS5


CREATE VIRTUAL TABLE Articles USING fts5(title, content);
INSERT INTO Articles VALUES ('SQLite 教學', '內容...');
SELECT * FROM Articles WHERE Articles MATCH 'SQLite';

3. 日期時間處理


// SQLite 無 DateTime 型別,儲存為 TEXT (ISO8601) / REAL (Julian Day) / INTEGER (Unix Timestamp)
INSERT INTO Events (EventTime) VALUES (datetime('now'));           // 當下 UTC
INSERT INTO Events (EventTime) VALUES (strftime('%Y-%m-%d %H:%M:%S', 'now', 'localtime')); // 本地時間
SELECT date(EventTime) FROM Events;                                // 只取日期
SELECT * FROM Events WHERE EventTime > datetime('now', '-7 days'); // 最近 7 天

效能優化清單

  • WAL 模式:PRAGMA journal_mode=WAL; (讀寫並行、不阻塞讀取)
  • 交易批次:單次交易提交百/千筆 INSERT
  • 索引建立:CREATE INDEX idx_users_name ON Users(UserName);
  • 連線共用:ASP.NET 應用使用連線池,避免頻繁 Open/Close
  • 參數重用:循環插入時建立一次 Command/Parameters,循環內只賦值

常見坑點

總結

SQLite 在 ASP.NET 中是輕量級、零設定、單檔案的優秀選擇,適合:中小型網站、嵌入式裝置、單元測試資料庫、本地快取、桌面應用配套資料。關鍵成功因素:參數化查詢防注入、交易批次寫入、WAL 模式並行、正確日期時間格式、原生 DLL 架構匹配。配合 System.Data.SQLite.Core NuGet 套件,部署極簡單 (僅需複製資料庫檔案)。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
問題原因解決
無法寫入 (readonly)App_Data 目錄權限不足 / 資料庫檔案唯讀屬性IIS_IUSRS 給予 App_Data 修改權限
System.BadImageFormatExceptionx86/x64 原生 DLL 不匹配安裝 System.Data.SQLite.Core 含雙架構原生庫,或專案設定 Prefer 32-bit
資料庫鎖定 (database is locked)多執行緒無 WAL / 連線未關閉 / 長交易啟用 WAL、using 區塊確保 Dispose、縮短交易範圍
DateTime 比較錯誤字串比較非時間比較統一儲存 ISO8601 UTC (yyyy-MM-ddTHH:mm:ssZ),查詢用 date()/datetime() 函數