GKTGD 工业监控系统-03SQLite 数据库技术文档(类库:NET8_SQLData)

📖 文档概述

本文档详细介绍了 GKTGD 工程中 SQLite 数据库的完整实现,包括嵌入式数据库原理、文件存储机制、ORM映射、数据操作和移植指南。通过本文档,开发者可以深入理解 SQLite 数据库的工作原理,并将其成功移植到其他项目中。

文档版本 : v1.0
适用项目 : GKTGD 工业自动化控制系统
技术框架 : .NET 8.0 + SQLite 3 + SqlSugar ORM
编写日期 : 2026-05-11
数据库版本: SQLite 3.0+


🎯 第一部分:SQLite 数据库基础

1.1 为什么选择 SQLite?

SQLite 核心优势

零配置特性

  • 无服务器: 无需数据库服务器进程,直接读写本地文件
  • 零配置: 不需要安装和配置,开箱即用
  • 单一文件: 整个数据库就是一个文件,便于备份和迁移
  • 跨平台: 支持 Windows、Linux、macOS、Android、iOS
  • 轻量级: 核心库小于 1MB,内存占用极小

适用场景

  • 本地配置存储: 通讯配置、设备参数、用户设置
  • 桌面应用程序: 单机版应用、移动应用
  • 嵌入式系统: IoT 设备、工业终端
  • 原型开发: 快速开发和测试
  • 小数据量: 通常小于 100GB 的数据
SQLite vs MySQL 对比
特性 SQLite MySQL
部署方式 嵌入式,单文件 客户端-服务器架构
数据存储 单个 .db 文件 多个文件和目录
并发性能 ⭐⭐⭐ (写操作串行) ⭐⭐⭐⭐⭐ (并发读写)
事务支持 完整ACID 完整ACID
网络访问 ❌ 不支持 ✅ 原生支持
学习难度 简单 中等
配置复杂度 零配置 需要配置服务器
适用场景 本地应用、配置存储 企业应用、多用户并发

选择建议

  • 使用 SQLite: 本地配置、单机应用、原型开发、嵌入式设备
  • 使用 MySQL: 多用户并发、大数据量、网络访问、企业应用

1.2 SQLite 工作原理

文件结构

SQLite 数据库就是一个普通的文件:

复制代码
项目目录/
├── bin/
│   └── Debug/
│       └── net8.0-windows/
│           ├── gktgd_local.db      # SQLite 数据库文件 ⭐
│           ├── gktgd_local.db-shm  # 共享内存文件(WAL模式)
│           └── gktgd_local.db-wal  # 写前日志文件(WAL模式)

文件说明

  • gktgd_local.db: 主数据库文件,包含所有表和数据
  • gktgd_local.db-shm: 共享内存文件,用于WAL模式
  • gktgd_local.db-wal: 写前日志,提高并发性能
数据库架构
复制代码
┌─────────────────────────────────────────────────────────────┐
│                    SQLite 数据库文件                          │
├─────────────────────────────────────────────────────────────┤
│                                                               │
│  ┌──────────────────┐      ┌──────────────────────────┐   │
│  │   表1: Users     │      │   表2: Roles            │   │
│  │  - Id            │      │  - Id                   │   │
│  │  - UserName      │      │  - RoleName             │   │
│  │  - Password      │      │  - Description          │   │
│  └──────────────────┘      └──────────────────────────┘   │
│                                                               │
│  ┌──────────────────┐      ┌──────────────────────────┐   │
│  │   表3: Configs   │      │   表4: Logs             │   │
│  │  - Id            │      │  - Id                   │   │
│  │  - Key           │      │  - Message              │   │
│  │  - Value         │      │  - Timestamp            │   │
│  └──────────────────┘      └──────────────────────────┘   │
│                                                               │
│  ┌──────────────────────────────────────────────────────┐  │
│  │         系统表: sqlite_master, sqlite_sequence      │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                               │
└─────────────────────────────────────────────────────────────┘

1.3 SQLite 限制和注意事项

技术限制
限制项 限制值 说明
最大数据库大小 281 TB 理论值,实际受文件系统限制
最大单行数据 1 GB 包含所有字段的总大小
最大字符串长度 1 GB 单个 TEXT 字段
最大列数 2000 单个表的列数
并发写操作 1次 同时只允许一个写操作
表名长度 2000 字符 标识符最大长度
注意事项

1. 并发写限制

csharp 复制代码
// SQLite 同时只允许一个写操作
// 多个线程写数据库时需要加锁
lock (_writeLock)
{
    client.Insertable(entity).ExecuteCommand();
}

2. 文件权限

bash 复制代码
# 确保应用程序有数据库文件的读写权限
chmod 664 gktgd_local.db

3. 定期维护

sql 复制代码
-- 定期执行 VACUUM 回收空间
VACUUM;

-- 重建索引
REINDEX;

🔧 第二部分:项目集成配置

2.1 NuGet 包安装

安装 SqlSugarCore

SQLite 是通过 SqlSugar ORM 框架访问的,不需要额外的 SQLite 驱动包。

方法1:通过 Visual Studio

  1. 右键项目 → 管理 NuGet 程序包
  2. 搜索 SqlSugarCore
  3. 选择版本 5.1.4.214 或更高
  4. 点击 安装

方法2:通过包管理器控制台

powershell 复制代码
Install-Package SqlSugarCore -Version 5.1.4.214

方法3:通过 .csproj 文件

编辑 NET8_SQLData.csproj

xml 复制代码
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net8.0-windows</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <!-- SqlSugar ORM 核心包(已包含 SQLite 支持) -->
    <PackageReference Include="SqlSugarCore" Version="5.1.4.214" />
    
    <!-- 配置文件读取包 -->
    <PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="9.0.7" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.7" />
  </ItemGroup>

  <ItemGroup>
    <!-- 项目引用 -->
    <ProjectReference Include="..\NET8_DataConvertLib\NET8_DataConvertLib.csproj" />
  </ItemGroup>
</Project>

2.2 连接字符串配置

appsettings.json 配置

文件位置 : GKTGD/appsettings.json

json 复制代码
{
  "ConnectionStrings": {
    "LocalSQLite": "Data Source=gktgd_local.db"
  }
}
连接字符串参数详解
参数 说明 示例值 必填
Data Source 数据库文件路径 gktgd_local.db
Version SQLite 版本 3 ❌ (默认3)
Cache Size 缓存大小(页数) -2000
Journal Mode 日志模式 WAL
Pooling 是否启用连接池 True

完整连接字符串示例

json 复制代码
{
  "ConnectionStrings": {
    // 基础配置
    "LocalSQLite": "Data Source=gktgd_local.db",

    // 高级配置
    "LocalSQLite_Advanced": "Data Source=gktgd_local.db;Version=3;Pooling=True;Max Pool Size=100;Journal Mode=WAL;Cache Size=-2000;",

    // 绝对路径
    "LocalSQLite_Absolute": "Data Source=D:\\Database\\gktgd_local.db",

    // 只读模式
    "LocalSQLite_ReadOnly": "Data Source=gktgd_local.db;Mode=ReadOnly"
  }
}
数据库文件路径说明

相对路径(推荐):

json 复制代码
{
  "LocalSQLite": "Data Source=gktgd_local.db"
}
  • 相对于应用程序的根目录
  • 通常在 bin\Debug\net8.0-windows\ 目录下
  • 便于部署和迁移

绝对路径

json 复制代码
{
  "LocalSQLite": "Data Source=D:\\Data\\gktgd_local.db"
}
  • 固定位置存储
  • 适用于多应用共享同一数据库

环境变量路径

json 复制代码
{
  "LocalSQLite": "Data Source=%APPDATA%\\GKTGD\\gktgd_local.db"
}
  • 使用系统环境变量
  • 符合 Windows 应用规范

2.3 项目文件结构

NET8_SQLData 项目结构(SQLite 部分)
复制代码
NET8_SQLData/
├── Core/                              # 核心类目录
│   ├── DbManager.cs                  # 数据库管理器
│   ├── DbConfig.cs                   # 数据库配置模型
│   ├── LocalSQLiteDb.cs              # 本地SQLite静态类 ⭐
│   ├── LocalMySQLDb.cs               # 本地MySQL静态类
│   └── RemoteMySQLDb.cs              # 远程MySQL静态类
├── Models/                            # 数据模型目录
│   └── SQLite/                        # SQLite数据模型 ⭐
│       ├── SQL_ModbusRTUEntity.cs    # ModBus RTU配置 ⭐
│       ├── SQL_ModbusTCPEntity.cs    # ModBus TCP配置 ⭐
│       ├── SQL_SiemensS7Entity.cs    # 西门子S7配置 ⭐
│       ├── SQL_MitsubishiMCEntity.cs # 三菱MC配置 ⭐
│       ├── SQL_BeckhoffADSEntity.cs # Beckhoff ADS配置 ⭐
│       ├── SQL_EtherNETEntity.cs     # EtherNet配置 ⭐
│       ├── SQL_CameraEntity.cs       # 相机配置 ⭐
│       ├── SQL_ZmotionEntity.cs      # 正运动控制器配置 ⭐
│       └── SQL_ACSEntity.cs          # ACS运动控制器配置 ⭐
├── Services/                          # 服务层目录
│   └── SQLite/                        # SQLite服务实现 ⭐
│       ├── SQL_ModbusRTUEntity_Service.cs
│       ├── SQL_ModbusTCPEntity_Service.cs
│       ├── SQL_SiemensS7Entity_Service.cs
│       ├── SQL_MitsubishiMCEntity_Service.cs
│       ├── SQL_BeckhoffADSEntity_Service.cs
│       ├── SQL_EtherNETEntity_Service.cs
│       ├── SQL_CameraEntity_Service.cs
│       ├── SQL_ZmotionEntity_Service.cs
│       └── SQL_ACSEntity_Service.cs
├── Interfaces/                        # 接口目录
│   ├── IDataService.cs               # 数据服务接口
│   └── IRepository.cs                # 仓储接口
└── NET8_SQLData.csproj              # 项目文件

⭐ 标记: 核心文件,需要重点理解


🏗️ 第三部分:核心代码架构

3.1 LocalSQLiteDb 静态类

完整实现代码

文件位置 : NET8_SQLData/Core/LocalSQLiteDb.cs

csharp 复制代码
using SqlSugar;

namespace NET8_SQLData.Core
{
    /// <summary>
    /// 本地SQLite数据库静态类
    /// </summary>
    public static class LocalSQLiteDb
    {
        private static SqlSugarClient? _client;

        /// <summary>
        /// 获取 SQLite 数据库客户端
        /// </summary>
        public static SqlSugarClient Client
        {
            get
            {
                if (_client == null)
                    throw new InvalidOperationException("LocalSQLiteDb 未初始化,请先调用 DbManager.Initialize()");
                return _client;
            }
        }

        /// <summary>
        /// 设置数据库客户端(由 DbManager 调用)
        /// </summary>
        internal static void SetClient(SqlSugarClient client) => _client = client;

        /// <summary>
        /// 查询所有数据
        /// </summary>
        public static List<T> QueryList<T>() where T : class, new() => 
            Client.Queryable<T>().ToList();

        /// <summary>
        /// 插入单条数据
        /// </summary>
        public static bool Insert<T>(T entity) where T : class, new() => 
            Client.Insertable(entity).ExecuteCommand() > 0;

        /// <summary>
        /// 更新数据
        /// </summary>
        public static bool Update<T>(T entity) where T : class, new() => 
            Client.Updateable(entity).ExecuteCommand() > 0;

        /// <summary>
        /// 删除数据
        /// </summary>
        public static bool Delete<T>(object id) where T : class, new() => 
            Client.Deleteable<T>().In(id).ExecuteCommand() > 0;
    }
}

设计特点

  • 静态方法: 无需实例化,直接通过类名调用
  • 泛型支持: 支持任何实体类型
  • 简洁API: 封装常用CRUD操作
  • 统一接口: 与 LocalMySQLDb 保持一致的调用方式

3.2 DbManager 集成

DbManager 会自动初始化 SQLite 数据库:

csharp 复制代码
// DbManager.cs 中的初始化代码
var localSQLite = connectionStrings["LocalSQLite"];
if (!string.IsNullOrEmpty(localSQLite))
{
    _dbConfigs.Add(new DbConfig
    {
        ConnectionString = localSQLite,
        DbType = DbType.Sqlite,  // 指定为 SQLite 类型
        ConfigName = "LocalSQLite"
    });
}

3.3 数据库初始化流程

App.xaml.cs 中的初始化
csharp 复制代码
protected override void OnStartup(StartupEventArgs e)
{
    base.OnStartup(e);

    // 1. 加载配置文件
    var builder = new ConfigurationBuilder()
        .SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
        .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
    
    var configuration = builder.Build();

    // 2. 初始化数据库管理器(同时初始化 MySQL 和 SQLite)
    DbManager.Initialize(configuration);

    // 3. 创建 SQLite 表
    CreateSQLiteTables();

    // 4. 显示主窗口
    var mainWindow = new MainWindow();
    mainWindow.Show();
}

private void CreateSQLiteTables()
{
    try
    {
        System.Diagnostics.Debug.WriteLine("在SQLite数据库中创建通讯配置表...");

        // 创建 ModBus RTU 配置表
        DbManager.CreateTables<SQL_ModbusRTUEntity>("LocalSQLite");
        
        // 创建 ModBus TCP 配置表
        DbManager.CreateTables<SQL_ModbusTCPEntity>("LocalSQLite");
        
        // 创建西门子S7配置表
        DbManager.CreateTables<SQL_SiemensS7Entity>("LocalSQLite");
        
        // ... 其他表

        System.Diagnostics.Debug.WriteLine("SQLite表创建成功");
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.WriteLine($"创建SQLite表失败: {ex.Message}");
    }
}

💾 第四部分:数据模型设计

4.1 通讯配置实体类

ModBus RTU 配置实体

文件位置 : NET8_SQLData/Models/SQLite/SQL_ModbusRTUEntity.cs

csharp 复制代码
using SqlSugar;

namespace NET8_SQLData.Models.SQLite
{
    /// <summary>
    /// ModBus RTU通讯配置实体
    /// </summary>
    [SugarTable("SQL_ModbusRTUEntity")]
    public class SQL_ModbusRTUEntity
    {
        /// <summary>
        /// 配置ID - 主键,自增
        /// </summary>
        [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
        public int Id { get; set; }

        /// <summary>
        /// 配置名称 - 最大100字符
        /// </summary>
        [SugarColumn(Length = 100)]
        public string ConfigName { get; set; } = string.Empty;

        /// <summary>
        /// 串口号 - 最大20字符,默认COM1
        /// </summary>
        [SugarColumn(Length = 20)]
        public string ComPort { get; set; } = "COM1";

        /// <summary>
        /// 波特率 - 最大20字符,默认9600
        /// </summary>
        [SugarColumn(Length = 20)]
        public string BaudRate { get; set; } = "9600";

        /// <summary>
        /// 数据位 - 最大10字符,默认8
        /// </summary>
        [SugarColumn(Length = 10)]
        public string DataBits { get; set; } = "8";

        /// <summary>
        /// 校验位 - 最大20字符,默认无
        /// </summary>
        [SugarColumn(Length = 20)]
        public string Parity { get; set; } = "无";

        /// <summary>
        /// 停止位 - 最大10字符,默认1
        /// </summary>
        [SugarColumn(Length = 10)]
        public string StopBits { get; set; } = "1";

        /// <summary>
        /// 从站地址 - 最大10字符,默认1
        /// </summary>
        [SugarColumn(Length = 10)]
        public string SlaveAddress { get; set; } = "1";

        /// <summary>
        /// 创建时间 - 可空
        /// </summary>
        [SugarColumn(IsNullable = true)]
        public DateTime? CreatedTime { get; set; }

        /// <summary>
        /// 更新时间 - 可空
        /// </summary>
        [SugarColumn(IsNullable = true)]
        public DateTime? UpdatedTime { get; set; }
    }
}
其他通讯配置实体

ModBus TCP 配置

csharp 复制代码
[SugarTable("SQL_ModbusTCPEntity")]
public class SQL_ModbusTCPEntity
{
    [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
    public int Id { get; set; }

    [SugarColumn(Length = 100)]
    public string ConfigName { get; set; } = string.Empty;

    [SugarColumn(Length = 50)]
    public string IpAddress { get; set; } = "192.168.1.100";

    [SugarColumn(Length = 10)]
    public string Port { get; set; } = "502";

    [SugarColumn(Length = 10)]
    public string SlaveAddress { get; set; } = "1";

    [SugarColumn(IsNullable = true)]
    public DateTime? CreatedTime { get; set; }

    [SugarColumn(IsNullable = true)]
    public DateTime? UpdatedTime { get; set; }
}

西门子S7配置

csharp 复制代码
[SugarTable("SQL_SiemensS7Entity")]
public class SQL_SiemensS7Entity
{
    [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
    public int Id { get; set; }

    [SugarColumn(Length = 100)]
    public string ConfigName { get; set; } = string.Empty;

    [SugarColumn(Length = 50)]
    public string IpAddress { get; set; } = "192.168.1.100";

    [SugarColumn(Length = 10)]
    public string Rack { get; set; } = "0";

    [SugarColumn(Length = 10)]
    public string Slot { get; set; } = "1";

    [SugarColumn(IsNullable = true)]
    public DateTime? CreatedTime { get; set; }

    [SugarColumn(IsNullable = true)]
    public DateTime? UpdatedTime { get; set; }
}

4.2 SQLite 表结构

自动创建的表结构

SQL_ModbusRTUEntity 表

sql 复制代码
CREATE TABLE "SQL_ModbusRTUEntity" (
  "Id" INTEGER PRIMARY KEY AUTOINCREMENT,
  "ConfigName" TEXT(100) NOT NULL,
  "ComPort" TEXT(20) NOT NULL,
  "BaudRate" TEXT(20) NOT NULL,
  "DataBits" TEXT(10) NOT NULL,
  "Parity" TEXT(20) NOT NULL,
  "StopBits" TEXT(10) NOT NULL,
  "SlaveAddress" TEXT(10) NOT NULL,
  "CreatedTime" TEXT,
  "UpdatedTime" TEXT
);

SQLite 数据类型说明

C# 类型 SQLite 类型 说明
int INTEGER 整数,自增主键
long INTEGER 长整数
string TEXT 文本字符串
DateTime TEXT 日期时间(以字符串形式存储)
bool INTEGER 0 或 1
decimal REAL 浮点数
byte[] BLOB 二进制数据

SQLite 特性

  • 动态类型: SQLite 使用动态类型系统,类型信息存储在值本身而非列中
  • TEXT 存储日期: DateTime 以文本格式存储(ISO8601标准)
  • 自动索引: 主键列自动创建索引

🚀 第五部分:数据操作服务

5.1 ModBus RTU 配置服务

完整实现代码

文件位置 : NET8_SQLData/Services/SQLite/SQL_ModbusRTUEntity_Service.cs

csharp 复制代码
using NET8_DataConvertLib;
using NET8_SQLData.Core;
using NET8_SQLData.Models.SQLite;
using SqlSugar;

namespace NET8_SQLData.Services.SQLite
{
    /// <summary>
    /// ModBus RTU配置服务
    /// </summary>
    public class SQL_ModbusRTUEntity_Service
    {
        /// <summary>
        /// 获取SQLite数据库客户端
        /// </summary>
        private SqlSugarClient GetClient()
        {
            try
            {
                return LocalSQLiteDb.Client;
            }
            catch (InvalidOperationException ex)
            {
                System.Diagnostics.Debug.WriteLine($"LocalSQLite未初始化: {ex.Message}");
                throw new InvalidOperationException(
                    "通讯配置数据必须存储在SQLite数据库。" +
                    "请检查appsettings.json中LocalSQLite配置是否正确。", ex);
            }
        }

        /// <summary>
        /// 添加ModBus RTU配置
        /// </summary>
        public OperateResult AddConfig(SQL_ModbusRTUEntity config)
        {
            try
            {
                // 设置创建时间
                config.CreatedTime = DateTime.Now;
                config.UpdatedTime = DateTime.Now;

                int result = GetClient().Insertable<SQL_ModbusRTUEntity>(config).ExecuteCommand();
                return result == 1 
                    ? OperateResult.CreateSuccessResult() 
                    : OperateResult.CreateFailResult("受影响的行数不为1");
            }
            catch (Exception ex)
            {
                return OperateResult.CreateFailResult(ex.Message);
            }
        }

        /// <summary>
        /// 删除ModBus RTU配置
        /// </summary>
        public OperateResult DeleteConfig(int configId)
        {
            try
            {
                int result = GetClient().Deleteable<SQL_ModbusRTUEntity>()
                    .Where(c => c.Id == configId)
                    .ExecuteCommand();
                return result == 1 
                    ? OperateResult.CreateSuccessResult() 
                    : OperateResult.CreateFailResult("受影响的行数不为1");
            }
            catch (Exception ex)
            {
                return OperateResult.CreateFailResult(ex.Message);
            }
        }

        /// <summary>
        /// 更新ModBus RTU配置
        /// </summary>
        public OperateResult UpdateConfig(SQL_ModbusRTUEntity config)
        {
            try
            {
                // 设置更新时间
                config.UpdatedTime = DateTime.Now;

                int result = GetClient().Updateable(config)
                    .WhereColumns(c => c.Id)  // 根据Id更新
                    .ExecuteCommand();
                return result == 1 
                    ? OperateResult.CreateSuccessResult() 
                    : OperateResult.CreateFailResult("受影响的行数不为1");
            }
            catch (Exception ex)
            {
                return OperateResult.CreateFailResult(ex.Message);
            }
        }

        /// <summary>
        /// 获取所有ModBus RTU配置
        /// </summary>
        public OperateResult<List<SQL_ModbusRTUEntity>> GetAllConfigs()
        {
            try
            {
                var configs = GetClient().Queryable<SQL_ModbusRTUEntity>()
                    .OrderByDescending(c => c.CreatedTime)  // 按创建时间降序
                    .ToList();
                return OperateResult.CreateSuccessResult(configs);
            }
            catch (Exception ex)
            {
                return OperateResult.CreateFailResult<List<SQL_ModbusRTUEntity>>(ex.Message);
            }
        }

        /// <summary>
        /// 根据ID获取ModBus RTU配置
        /// </summary>
        public OperateResult<SQL_ModbusRTUEntity> GetConfigById(int configId)
        {
            try
            {
                var config = GetClient().Queryable<SQL_ModbusRTUEntity>()
                    .Where(c => c.Id == configId)
                    .First();

                if (config != null)
                    return OperateResult.CreateSuccessResult(config);
                else
                    return OperateResult.CreateFailResult<SQL_ModbusRTUEntity>("配置不存在");
            }
            catch (Exception ex)
            {
                return OperateResult.CreateFailResult<SQL_ModbusRTUEntity>(ex.Message);
            }
        }

        /// <summary>
        /// 根据配置名称获取配置
        /// </summary>
        public OperateResult<SQL_ModbusRTUEntity> GetConfigByName(string configName)
        {
            try
            {
                var config = GetClient().Queryable<SQL_ModbusRTUEntity>()
                    .Where(c => c.ConfigName == configName)
                    .First();

                if (config != null)
                    return OperateResult.CreateSuccessResult(config);
                else
                    return OperateResult.CreateFailResult<SQL_ModbusRTUEntity>($"配置'{configName}'不存在");
            }
            catch (Exception ex)
            {
                return OperateResult.CreateFailResult<SQL_ModbusRTUEntity>(ex.Message);
            }
        }

        /// <summary>
        /// 检查配置名称是否存在
        /// </summary>
        public OperateResult<bool> CheckConfigNameExists(string configName)
        {
            try
            {
                int count = GetClient().Queryable<SQL_ModbusRTUEntity>()
                    .Where(c => c.ConfigName == configName)
                    .Count();
                return OperateResult.CreateSuccessResult(count > 0);
            }
            catch (Exception ex)
            {
                return OperateResult.CreateFailResult<bool>(ex.Message);
            }
        }

        /// <summary>
        /// 批量删除配置
        /// </summary>
        public OperateResult BatchDeleteConfigs(List<int> configIds)
        {
            try
            {
                int result = GetClient().Deleteable<SQL_ModbusRTUEntity>()
                    .In(configIds)
                    .ExecuteCommand();
                return OperateResult.CreateSuccessResult($"成功删除 {result} 个配置");
            }
            catch (Exception ex)
            {
                return OperateResult.CreateFailResult(ex.Message);
            }
        }
    }
}

5.2 服务方法使用示例

添加配置
csharp 复制代码
var service = new SQL_ModbusRTUEntity_Service();

var newConfig = new SQL_ModbusRTUEntity
{
    ConfigName = "设备1-RTU",
    ComPort = "COM3",
    BaudRate = "19200",
    DataBits = "8",
    Parity = "无",
    StopBits = "1",
    SlaveAddress = "1"
};

var result = service.AddConfig(newConfig);
if (result.IsSuccess)
{
    Console.WriteLine("配置添加成功");
}
else
{
    Console.WriteLine($"添加失败: {result.Message}");
}
查询所有配置
csharp 复制代码
var service = new SQL_ModbusRTUEntity_Service();

var result = service.GetAllConfigs();
if (result.IsSuccess)
{
    foreach (var config in result.Content)
    {
        Console.WriteLine($"{config.ConfigName}: {config.ComPort} @ {config.BaudRate}");
    }
}
更新配置
csharp 复制代码
var service = new SQL_ModbusRTUEntity_Service();

// 先查询现有配置
var getResult = service.GetConfigById(1);
if (getResult.IsSuccess)
{
    var config = getResult.Content;
    config.BaudRate = "38400";  // 修改波特率
    config.UpdatedTime = DateTime.Now;

    var updateResult = service.UpdateConfig(config);
    if (updateResult.IsSuccess)
    {
        Console.WriteLine("配置更新成功");
    }
}
删除配置
csharp 复制代码
var service = new SQL_ModbusRTUEntity_Service();

var result = service.DeleteConfig(1);
if (result.IsSuccess)
{
    Console.WriteLine("配置删除成功");
}
else
{
    Console.WriteLine($"删除失败: {result.Message}");
}

📱 第六部分:实际应用集成

6.1 ViewModel 中使用 SQLite 服务

系统设置 ViewModel

文件位置 : GKTGD/ViewModels/SystemSettings/SystemSettingsTask1ViewModel.cs

csharp 复制代码
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using NET8_SQLData.Models.SQLite;
using NET8_SQLData.Services.SQLite;
using System.Windows;

namespace GKTGD.ViewModels.SystemSettings
{
    public partial class SystemSettingsTask1ViewModel : ViewModelBase
    {
        private readonly SQL_ModbusRTUEntity_Service _modbusRTUService;
        private readonly SQL_ModbusTCPEntity_Service _modbusTCPService;

        [ObservableProperty]
        private List<SQL_ModbusRTUEntity> _modbusRTUConfigs = new();

        [ObservableProperty]
        private SQL_ModbusRTUEntity? _editingConfig;

        [ObservableProperty]
        private string _configName = string.Empty;

        [ObservableProperty]
        private string _comPort = "COM1";

        [ObservableProperty]
        private string _baudRate = "9600";

        public SystemSettingsTask1ViewModel()
        {
            _modbusRTUService = new SQL_ModbusRTUEntity_Service();
            _modbusTCPService = new SQL_ModbusTCPEntity_Service();
            
            LoadModbusRTUConfigs();
        }

        /// <summary>
        /// 加载 ModBus RTU 配置列表
        /// </summary>
        [RelayCommand]
        private void LoadModbusRTUConfigs()
        {
            var result = _modbusRTUService.GetAllConfigs();
            if (result.IsSuccess)
            {
                ModbusRTUConfigs = result.Content;
                System.Diagnostics.Debug.WriteLine($"成功加载 {ModbusRTUConfigs.Count} 个ModBus RTU配置");
            }
            else
            {
                MessageBox.Show($"加载配置失败: {result.Message}", "错误");
            }
        }

        /// <summary>
        /// 添加新配置
        /// </summary>
        [RelayCommand]
        private async Task AddModbusRTUConfigAsync()
        {
            // 验证输入
            if (string.IsNullOrWhiteSpace(ConfigName))
            {
                MessageBox.Show("请输入配置名称", "验证失败");
                return;
            }

            // 检查配置名称是否已存在
            var checkResult = _modbusRTUService.CheckConfigNameExists(ConfigName);
            if (checkResult.IsSuccess && checkResult.Content)
            {
                MessageBox.Show("配置名称已存在", "验证失败");
                return;
            }

            // 创建新配置
            var newConfig = new SQL_ModbusRTUEntity
            {
                ConfigName = ConfigName,
                ComPort = ComPort,
                BaudRate = BaudRate,
                DataBits = "8",
                Parity = "无",
                StopBits = "1",
                SlaveAddress = "1"
            };

            var result = await Task.Run(() => _modbusRTUService.AddConfig(newConfig));
            
            if (result.IsSuccess)
            {
                MessageBox.Show("ModBus RTU 配置添加成功", "成功");
                LoadModbusRTUConfigs();  // 刷新列表
            }
            else
            {
                MessageBox.Show($"添加配置失败: {result.Message}", "错误");
            }
        }

        /// <summary>
        /// 更新配置
        /// </summary>
        [RelayCommand]
        private async Task UpdateModbusRTUConfigAsync()
        {
            if (EditingConfig == null)
            {
                MessageBox.Show("请先选择要编辑的配置", "提示");
                return;
            }

            // 更新配置信息
            EditingConfig.ConfigName = ConfigName;
            EditingConfig.ComPort = ComPort;
            EditingConfig.BaudRate = BaudRate;

            var result = await Task.Run(() => _modbusRTUService.UpdateConfig(EditingConfig));
            
            if (result.IsSuccess)
            {
                MessageBox.Show("ModBus RTU 配置更新成功", "成功");
                LoadModbusRTUConfigs();  // 刷新列表
            }
            else
            {
                MessageBox.Show($"更新配置失败: {result.Message}", "错误");
            }
        }

        /// <summary>
        /// 删除配置
        /// </summary>
        [RelayCommand]
        private async Task DeleteModbusRTUConfigAsync()
        {
            if (EditingConfig == null)
            {
                MessageBox.Show("请先选择要删除的配置", "提示");
                return;
            }

            var confirm = MessageBox.Show(
                $"确定要删除配置 '{EditingConfig.ConfigName}' 吗?", 
                "确认删除", 
                MessageBoxButton.YesNo, 
                MessageBoxImage.Question);

            if (confirm == MessageBoxResult.Yes)
            {
                var result = await Task.Run(() => _modbusRTUService.DeleteConfig(EditingConfig.Id));
                
                if (result.IsSuccess)
                {
                    MessageBox.Show("ModBus RTU 配置删除成功", "成功");
                    LoadModbusRTUConfigs();  // 刷新列表
                }
                else
                {
                    MessageBox.Show($"删除配置失败: {result.Message}", "错误");
                }
            }
        }
    }
}

6.2 多种通讯配置管理

统一配置管理器
csharp 复制代码
public class CommunicationConfigManager
{
    private readonly SQL_ModbusRTUEntity_Service _modbusRTUService;
    private readonly SQL_ModbusTCPEntity_Service _modbusTCPService;
    private readonly SQL_SiemensS7Entity_Service _siemensS7Service;

    public CommunicationConfigManager()
    {
        _modbusRTUService = new SQL_ModbusRTUEntity_Service();
        _modbusTCPService = new SQL_ModbusTCPEntity_Service();
        _siemensS7Service = new SQL_SiemensS7Entity_Service();
    }

    /// <summary>
    /// 获取所有配置(混合类型)
    /// </summary>
    public List<object> GetAllConfigs()
    {
        var allConfigs = new List<object>();

        // 添加 ModBus RTU 配置
        var rtuResult = _modbusRTUService.GetAllConfigs();
        if (rtuResult.IsSuccess)
        {
            allConfigs.AddRange(rtuResult.Content);
        }

        // 添加 ModBus TCP 配置
        var tcpResult = _modbusTCPService.GetAllConfigs();
        if (tcpResult.IsSuccess)
        {
            allConfigs.AddRange(tcpResult.Content);
        }

        // 添加西门子S7配置
        var s7Result = _siemensS7Service.GetAllConfigs();
        if (s7Result.IsSuccess)
        {
            allConfigs.AddRange(s7Result.Content);
        }

        return allConfigs;
    }
}

🚀 第七部分:移植指南

7.1 移植到新项目完整步骤

步骤1:创建项目
  1. 创建新的 WPF 项目或类库项目
  2. 目标框架:.NET 8.0-windows
步骤2:安装依赖包
powershell 复制代码
# 在包管理器控制台执行
Install-Package SqlSugarCore -Version 5.1.4.214
Install-Package Microsoft.Extensions.Configuration.Abstractions -Version 9.0.7
Install-Package Microsoft.Extensions.Configuration.Json -Version 9.0.7
步骤3:复制核心文件

必需文件清单

复制代码
NET8_SQLData/
├── Core/
│   ├── DbManager.cs
│   ├── DbConfig.cs
│   └── LocalSQLiteDb.cs
├── Interfaces/
│   ├── IDataService.cs
│   └── IRepository.cs
└── NET8_SQLData.csproj
步骤4:配置连接字符串

创建 appsettings.json

json 复制代码
{
  "ConnectionStrings": {
    "LocalSQLite": "Data Source=your_database.db"
  }
}
步骤5:创建数据模型
csharp 复制代码
using SqlSugar;

namespace YourProject.Models
{
    [SugarTable("YourTable")]
    public class YourEntity
    {
        [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
        public int Id { get; set; }

        [SugarColumn(Length = 100)]
        public string Name { get; set; } = string.Empty;

        [SugarColumn(IsNullable = true)]
        public DateTime? CreatedTime { get; set; }

        [SugarColumn(IsNullable = true)]
        public DateTime? UpdatedTime { get; set; }
    }
}
步骤6:创建服务类
csharp 复制代码
using NET8_SQLData.Core;
using YourProject.Models;

namespace YourProject.Services
{
    public class YourEntityService
    {
        public List<YourEntity> GetAll()
        {
            return LocalSQLiteDb.QueryList<YourEntity>();
        }

        public bool Add(YourEntity entity)
        {
            entity.CreatedTime = DateTime.Now;
            entity.UpdatedTime = DateTime.Now;
            return LocalSQLiteDb.Insert(entity);
        }

        public bool Update(YourEntity entity)
        {
            entity.UpdatedTime = DateTime.Now;
            return LocalSQLiteDb.Update(entity);
        }

        public bool Delete(int id)
        {
            return LocalSQLiteDb.Delete<YourEntity>(id);
        }
    }
}
步骤7:初始化数据库

App.xaml.cs 中:

csharp 复制代码
protected override void OnStartup(StartupEventArgs e)
{
    base.OnStartup(e);

    // 加载配置
    var builder = new ConfigurationBuilder()
        .SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
        .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
    
    var configuration = builder.Build();

    // 初始化数据库
    DbManager.Initialize(configuration);

    // 创建表
    DbManager.CreateTables<YourEntity>("LocalSQLite");

    // 显示主窗口
    var mainWindow = new MainWindow();
    mainWindow.Show();
}

7.2 部署和分发

数据库文件处理

1. 包含空数据库文件

xml 复制代码
<!-- .csproj 文件 -->
<ItemGroup>
  <None Update="your_database.db">
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  </None>
</ItemGroup>

2. 运行时创建

csharp 复制代码
// 如果数据库文件不存在,自动创建
if (!File.Exists("your_database.db"))
{
    DbManager.CreateTables<YourEntity>("LocalSQLite");
}

3. 备份和恢复

csharp 复制代码
/// <summary>
/// 备份数据库
/// </summary>
public void BackupDatabase(string sourcePath, string backupPath)
{
    File.Copy(sourcePath, backupPath, true);
    Console.WriteLine($"数据库已备份到: {backupPath}");
}

/// <summary>
/// 恢复数据库
/// </summary>
public void RestoreDatabase(string backupPath, string targetPath)
{
    File.Copy(backupPath, targetPath, true);
    Console.WriteLine($"数据库已从 {backupPath} 恢复");
}

📊 第八部分:性能优化和最佳实践

8.1 SQLite 性能优化

1. 启用 WAL 模式

Write-Ahead Logging (WAL) 模式可以显著提高并发性能:

csharp 复制代码
// 在连接字符串中启用 WAL 模式
{
  "LocalSQLite": "Data Source=gktgd_local.db;Journal Mode=WAL;"
}

WAL 模式优势

  • 读写并发:读操作不会阻塞写操作
  • 更快的写入:减少磁盘 I/O
  • 更好的崩溃恢复:自动恢复未完成的事务
2. 调整缓存大小
json 复制代码
{
  "LocalSQLite": "Data Source=gktgd_local.db;Cache Size=-10000;"
}

参数说明

  • 负值:KB 为单位,-10000 = 10MB
  • 正值:页数为单位,10000 = 40MB(默认页大小4KB)
3. 批量操作优化
csharp 复制代码
// ❌ 不好:循环插入
foreach (var config in configs)
{
    client.Insertable(config).ExecuteCommand();
}

// ✅ 好:批量插入
client.Insertable(configs).ExecuteCommand();
4. 使用索引
csharp 复制代码
// 为常用查询字段创建索引
client.Ado.ExecuteCommand("CREATE INDEX IF NOT EXISTS IX_ConfigName ON SQL_ModbusRTUEntity(ConfigName);");

8.2 最佳实践

1. 使用事务
csharp 复制代码
public OperateResult BatchUpdateConfigs(List<SQL_ModbusRTUEntity> configs)
{
    try
    {
        var client = LocalSQLiteDb.Client;
        
        // 开启事务
        client.Ado.BeginTran();
        
        try
        {
            foreach (var config in configs)
            {
                client.Updateable(config).ExecuteCommand();
            }
            
            // 提交事务
            client.Ado.CommitTran();
            
            return OperateResult.CreateSuccessResult();
        }
        catch
        {
            // 回滚事务
            client.Ado.RollbackTran();
            throw;
        }
    }
    catch (Exception ex)
    {
        return OperateResult.CreateFailResult(ex.Message);
    }
}
2. 定期维护
csharp 复制代码
/// <summary>
/// 数据库维护
/// </summary>
public void PerformMaintenance()
{
    try
    {
        var client = LocalSQLiteDb.Client;
        
        // 回收空间
        client.Ado.ExecuteCommand("VACUUM;");
        
        // 重建索引
        client.Ado.ExecuteCommand("REINDEX;");
        
        // 分析表统计信息
        client.Ado.ExecuteCommand("ANALYZE;");
        
        Console.WriteLine("数据库维护完成");
    }
    catch (Exception ex)
    {
        Console.WriteLine($"数据库维护失败: {ex.Message}");
    }
}
3. 数据库文件大小监控
csharp 复制代码
/// <summary>
/// 获取数据库文件大小
/// </summary>
public long GetDatabaseSize()
{
    try
    {
        var dbPath = "gktgd_local.db";
        if (File.Exists(dbPath))
        {
            var fileInfo = new FileInfo(dbPath);
            return fileInfo.Length;
        }
        return 0;
    }
    catch (Exception ex)
    {
        Console.WriteLine($"获取数据库大小失败: {ex.Message}");
        return 0;
    }
}

// 格式化文件大小
public string FormatFileSize(long bytes)
{
    string[] sizes = { "B", "KB", "MB", "GB" };
    double len = bytes;
    int order = 0;
    while (len >= 1024 && order < sizes.Length - 1)
    {
        order++;
        len = len / 1024;
    }
    return $"{len:0.##} {sizes[order]}";
}

📞 第九部分:故障排除和FAQ

9.1 常见错误及解决方案

错误1:数据库文件锁定

错误信息:

复制代码
Unable to open database file: File is opened by another process

解决方案:

  1. 确保只有一个进程访问数据库文件
  2. 检查是否有其他应用程序打开了数据库文件
  3. 关闭所有数据库连接后重试
csharp 复制代码
// 确保连接池正确配置
{
  "LocalSQLite": "Data Source=gktgd_local.db;Pooling=True;Max Pool Size=100;"
}
错误2:表不存在

错误信息:

复制代码
Table 'SQL_ModbusRTUEntity' doesn't exist

解决方案:

确保已调用 CreateTables 方法:

csharp 复制代码
DbManager.CreateTables<SQL_ModbusRTUEntity>("LocalSQLite");
错误3:数据库文件损坏

错误信息:

复制代码
database disk image is malformed

解决方案:

  1. 从备份恢复数据库文件
  2. 尝试使用 SQLite 命令行工具修复:
bash 复制代码
sqlite3 gktgd_local.db "PRAGMA integrity_check;"
sqlite3 gktgd_local.db "VACUUM;"
  1. 如果无法修复,从备份恢复或重新创建数据库

9.2 调试技巧

1. 查看数据库文件位置
csharp 复制代码
public void ShowDatabaseInfo()
{
    var dbPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "gktgd_local.db");
    Console.WriteLine($"数据库文件路径: {dbPath}");
    Console.WriteLine($"文件存在: {File.Exists(dbPath)}");
    
    if (File.Exists(dbPath))
    {
        var fileInfo = new FileInfo(dbPath);
        Console.WriteLine($"文件大小: {FormatFileSize(fileInfo.Length)}");
        Console.WriteLine($"创建时间: {fileInfo.CreationTime}");
        Console.WriteLine($"修改时间: {fileInfo.LastWriteTime}");
    }
}
2. 查看表结构
csharp 复制代码
public void ShowTableStructure()
{
    try
    {
        var client = LocalSQLiteDb.Client;
        
        // 查询所有表
        var tables = client.Ado.GetDataTable("SELECT name FROM sqlite_master WHERE type='table';");
        Console.WriteLine("数据库中的表:");
        foreach (System.Data.DataRow row in tables.Rows)
        {
            Console.WriteLine($"- {row[0]}");
        }
        
        // 查询表结构
        var columns = client.Ado.GetDataTable("PRAGMA table_info(SQL_ModbusRTUEntity);");
        Console.WriteLine("\nSQL_ModbusRTUEntity 表结构:");
        foreach (System.Data.DataRow row in columns.Rows)
        {
            Console.WriteLine($"- {row[1]}: {row[2]}");
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine($"查询表结构失败: {ex.Message}");
    }
}
3. 测试数据库性能
csharp 复制代码
public void TestPerformance()
{
    var stopwatch = System.Diagnostics.Stopwatch.StartNew();
    
    // 测试插入性能
    var testConfig = new SQL_ModbusRTUEntity
    {
        ConfigName = "测试配置",
        ComPort = "COM1",
        BaudRate = "9600"
    };
    
    var iterations = 1000;
    for (int i = 0; i < iterations; i++)
    {
        LocalSQLiteDb.Insert(testConfig);
    }
    
    stopwatch.Stop();
    Console.WriteLine($"插入 {iterations} 条记录耗时: {stopwatch.ElapsedMilliseconds} ms");
    Console.WriteLine($"平均每条: {stopwatch.ElapsedMilliseconds / (double)iterations} ms");
}

🎓 第十部分:高级主题

10.1 数据库加密

使用 SQLCipher 加密

注意: SqlSugar 核心版本不支持加密,需要使用加密版本或第三方解决方案。

10.2 内存数据库

使用内存数据库进行测试

json 复制代码
{
  "LocalSQLite_Memory": "Data Source=:memory:"
}

内存数据库特点:

  • ✅ 极快的访问速度
  • ✅ 适合单元测试
  • ❌ 数据不持久,应用关闭后丢失

10.3 跨平台部署

路径处理
csharp 复制代码
/// <summary>
/// 获取跨平台数据库路径
/// </summary>
public string GetDatabasePath()
{
    string dbPath;
    
    if (Environment.OSVersion.Platform == PlatformID.Unix)
    {
        // Linux/Mac: 用户主目录
        dbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), ".config", "yourapp", "gktgd_local.db");
    }
    else
    {
        // Windows: 应用程序目录
        dbPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "gktgd_local.db");
    }
    
    // 确保目录存在
    var directory = Path.GetDirectoryName(dbPath);
    if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
    {
        Directory.CreateDirectory(directory);
    }
    
    return dbPath;
}

📚 附录

A. SQL 常用命令

sql 复制代码
-- 查看所有表
SELECT name FROM sqlite_master WHERE type='table';

-- 查看表结构
PRAGMA table_info(TableName);

-- 查看表创建语句
SELECT sql FROM sqlite_master WHERE type='table' AND name='TableName';

-- 删除表
DROP TABLE IF EXISTS TableName;

-- 清空表
DELETE FROM TableName;

-- 重置自增ID
DELETE FROM sqlite_sequence WHERE name='TableName';

-- 查看数据库文件大小(页数 * 页大小)
PRAGMA page_count;
PRAGMA page_size;

-- 优化数据库
VACUUM;
ANALYZE;

B. SQLite 数据类型对照

C# 类型 SQLite 类型 说明
int INTEGER 整数
long INTEGER 长整数
string TEXT 文本字符串
DateTime TEXT 日期时间(ISO8601格式)
bool INTEGER 0 或 1
decimal REAL 浮点数
byte[] BLOB 二进制数据
Guid TEXT GUID字符串

C. 日期时间格式

SQLite 推荐使用 ISO8601 格式存储日期时间:

csharp 复制代码
// 格式化日期时间
string iso8601 = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
// 示例: "2026-05-11 14:30:45"

// 查询日期范围
var configs = client.Queryable<SQL_ModbusRTUEntity>()
    .Where(c => c.CreatedTime >= startDate && c.CreatedTime <= endDate)
    .ToList();

D. 参考资料


文档结束

本文档详细介绍了 GKTGD 工程中 SQLite 数据库的完整实现,包括嵌入式数据库原理、连接配置、数据操作、性能优化和移植指南。通过本文档,开发者可以快速上手 SQLite 数据库开发,并将其成功移植到其他项目中。

文档版本 : v1.0
最后更新: 2026-05-11

相关推荐
duke8692672141 小时前
PHP怎么使用Eloquent Attribute Synthesis属性合成_Laravel多源数据融合【指南】
jvm·数据库·python
承渊政道1 小时前
Oracle迁移避坑:一个(+)写错,LEFT JOIN可能变INNER JOIN
运维·服务器·数据库·数据仓库·学习·安全·oracle
2301_812539671 小时前
CSS如何制作下拉菜单弹性展开_利用transform-origin
jvm·数据库·python
2401_833033621 小时前
CSS Flex布局中如何设置子元素间距_掌握gap属性的现代用法
jvm·数据库·python
阿坤带你走近大数据1 小时前
OracleSQL优化案例-3
数据库·oracle·sql优化
iuvtsrt1 小时前
SQL如何优化子查询的性能_改写为JOIN关联查询与消除嵌套
jvm·数据库·python
2403_883261091 小时前
C#怎么使用并发集合 C#ConcurrentDictionary和ConcurrentQueue线程安全集合怎么用【进阶】
jvm·数据库·python
m0_470857641 小时前
如何加固SQL系统架构_采用读写分离降低攻击影响
jvm·数据库·python
2401_884454151 小时前
Golang如何写博客系统后端_Golang博客系统教程【技巧】
jvm·数据库·python