《断网不丢日志,多机共享工单:高速龙门贴片机实战沉淀 SQLite + MySQL 双库分层架构实战-无硬件 Mock 可直接运行》
前言原单库版本拆分双存储职责,适配业务需求上面的可视化架构图帮你快速理解整个设计的核心思路:一句话总结:把"容易丢、要速度"的日志交给本地 SQLite,把"要共享、要统计"的工单交给服务端 MySQL,两者通过Service 接口层完全解耦,ViewModel 里一行 SQL 都没有。一、项目基础信息1. 目标框架TargetFrameworknet6.0-windows/TargetFramework UseWPFtrue/UseWPF2. 完整 NuGet 包清单(固定版本,一键批量安装)NuGet 控制台批量指令# MVVM核心 Install-Package CommunityToolkit.Mvvm -Version 8.2.2 # DI容器 Install-Package Microsoft.Extensions.DependencyInjection -Version 8.0.1 # EF Core核心 Install-Package Microsoft.EntityFrameworkCore -Version 8.0.1 # SQLite本地日志库 Install-Package Microsoft.EntityFrameworkCore.Sqlite -Version 8.0.1 # MySQL生产业务库 Install-Package Pomelo.EntityFrameworkCore.MySql -Version 8.0.1 # EF迁移工具 Install-Package Microsoft.EntityFrameworkCore.Tools -Version 8.0.1csproj 包引用片段ItemGroup PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" / PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" / PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.1" / PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.1" / PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="8.0.1" / PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.1" PrivateAssets="all" / /ItemGroup二、五层架构总览(双数据库改造点标注)基于 3 台量产龙门贴片机实战沉淀分层架构,严格遵循上层依赖下层,下层禁止反向依赖,Service 层通过回调 / 事件上报状态解耦循环依赖。目录结构(新增数据库相关目录)SMTMachineDemo/ ├─ HAL/ # 雷赛运动卡原生封装 │ └─ Dmc3000Native.cs ├─ Core/ │ ├─ Calibration/ # 九点标定算法 │ │ └─ MatrixTransform.cs │ ├─ DbContext/ # 双数据库上下文 │ │ ├─ SqliteLogDbContext.cs │ │ └─ MysqlProductionDbContext.cs │ └─ Entity/ # 双库实体 │ ├─ LogRecord.cs # SQLite日志表实体 │ └─ ProductionBatch.cs # MySQL生产批次实体 ├─ Models/ # 硬件状态数据模型 │ ├─ AxisStatus.cs │ └─ AxisStatusEventArgs.cs ├─ Services/ │ ├─ Interfaces/ │ │ ├─ IMotionService.cs │ │ ├─ ICameraService.cs │ │ ├─ ILogService.cs # 日志服务接口(SQLite实现) │ │ └─ IProductionService.cs # 生产数据接口(MySQL实现) │ ├─ MockMotionService.cs │ ├─ MockCameraService.cs │ ├─ MockLogService.cs # 内存模拟日志(无数据库演示) │ ├─ SqliteLogService.cs # SQLite持久化日志实现 │ ├─ MockProductionService.cs # 模拟生产数据 │ └─ MysqlProductionService.cs # MySQL真实生产库实现 ├─ ViewModels/ │ ├─ ViewModelBase.cs │ └─ MainViewModel.cs ├─ Converters/ │ └─ CollectionToStringConverter.cs ├─ App.xaml ├─ App.xaml.cs # DI注册双数据库、模拟/真机切换 └─ MainWindow.xaml三、分层完整可运行源码3.1 Core 数据库实体 DbContextCore/Entity/LogRecord.cs(SQLite 本地日志表)using Microsoft.EntityFrameworkCore; using System.ComponentModel.DataAnnotations; namespace SMTMachineDemo.Core.Entity; /// summary /// SQLite本地日志记录实体,断电不丢失 /// /summary [Index(nameof(CreateTime))] public class LogRecord { [Key] public long Id { get; set; } /// summary日志内容/summary public string Content { get; set; } = string.Empty; /// summary记录时间戳/summary public DateTime CreateTime { get; set; } /// summary日志等级:Info/Warn/Error/summary public string LogLevel { get; set; } = "Info"; }Core/Entity/ProductionBatch.cs(MySQL 生产工单批次)using Microsoft.EntityFrameworkCore; using System.ComponentModel.DataAnnotations; namespace SMTMachineDemo.Core.Entity; /// summary /// MySQL生产批次工单,多设备共享统计 /// /summary [Index(nameof(BatchNo), IsUnique = true)] [Index(nameof(ProduceStartTime))] public class ProductionBatch { [Key] public long Id { get; set; } /// summary生产批次号/summary [MaxLength(64)] public string BatchNo { get; set; } = string.Empty; /// summary产品型号/summary [MaxLength(128)] public string ProductModel { get; set; } = string.Empty; /// summary计划产量/summary public int PlanCount { get; set; } /// summary实际完成产量/summary public int ActualCount { get; set; } /// summary不良品数量/summary public int DefectCount { get; set; } /// summary生产开始时间/summary public DateTime ProduceStartTime { get; set; } /// summary生产结束时间/summary public DateTime? ProduceEndTime { get; set; } /// summary设备编号/summary [MaxLength(32)] public string DeviceSn { get; set; } = string.Empty; }Core/DbContext/SqliteLogDbContext.csusing Microsoft.EntityFrameworkCore; using SMTMachineDemo.Core.Entity; namespace SMTMachineDemo.Core.DbContext; /// summary /// SQLite本地日志数据库上下文 /// /summary public class SqliteLogDbContext : Microsoft.EntityFrameworkCore.DbContext { public DbSetLogRecord LogRecords { get; set; } = null!; private readonly string _connectionString; public SqliteLogDbContext(DbContextOptionsSqliteLogDbContext options) : base(options) { } protected override void OnModelCreating(ModelBuilder modelBuilder) { // 日志表按时间自动清理旧数据(保留30天) modelBuilder.EntityLogRecord() .HasData(); } }Core/DbContext/MysqlProductionDbContext.csusing Microsoft.EntityFrameworkCore; using SMTMachineDemo.Core.Entity; namespace SMTMachineDemo.Core.DbContext; /// summary /// MySQL服务端生产业务数据库上下文 /// /summary public class MysqlProductionDbContext : Microsoft.EntityFrameworkCore.DbContext { public DbSetProductionBatch ProductionBatches { get; set; } = null!; public MysqlProductionDbContext(DbContextOptionsMysqlProductionDbContext options) : base(options) { } protected override void OnModelCreating(ModelBuilder modelBuilder) { // MySQL字符集、排序规则配置 modelBuilder.EntityProductionBatch() .Property(x = x.BatchNo) .HasColumnType("varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"); } }Core/Calibration/MatrixTransform.cs(原有标定算法不变)namespace SMTMachineDemo.Core.Calibration; public static class PixelToMechanical { /// summary /// 九点标定仿射变换,像素坐标转机械轴坐标 /// /summary public static (double x, double y) Transform( double pixelX, double pixelY,

相关新闻

Docker Compose安装指南:二进制与pip方式详解及避坑实践

Docker Compose安装指南:二进制与pip方式详解及避坑实践

1. 为什么你需要关心docker-compose的安装方式? 如果你在Linux上折腾过Docker,大概率会遇到一个场景:你写好了一堆 docker run 命令,或者一个复杂的服务栈需要多个容器协同工作,每次启动都要手动敲一遍,…

2026/10/27 19:35:15 阅读更多 →
KKCE: 基于网站测速的WebRTC信令与ICE穿透延迟诊断-快快测

KKCE: 基于网站测速的WebRTC信令与ICE穿透延迟诊断-快快测

一、引言:为什么 TTFB 只有 30ms,视频首帧却要 5 秒? 在实时音视频应用里,我们习惯用 iperf 或简单的 HTTP 测速看网络质量。即便用 www.kkce.com 的 网站测速​ 对信令服务器做检测,TTFB 30ms、完全加载 80ms&#x…

2026/10/26 14:12:52 阅读更多 →
AgentScope Java Harness:10. Channel Agent 通信的“神经系统“设计

AgentScope Java Harness:10. Channel Agent 通信的“神经系统“设计

目录: 1. 如何优雅地驾驭长期运行的 AI Agent 2. 上下文压缩:让长期 Agent 永不“失忆“ 3. 工作区(Workspace)文件即真理,目录即架构 4. 双层记忆系统 让 Agent 拥有真正的“长期大脑“ 5. 文件系统一套代码&#xff…

2026/10/27 18:41:44 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/10/27 17:33:32 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/10/27 4:06:49 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/27 7:21:53 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/10/27 18:20:50 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/10/27 6:20:47 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/10/27 4:06:50 阅读更多 →

日新闻

周新闻

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/27 13:55:19 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/27 7:21:50 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/27 19:19:37 阅读更多 →