项目 6 数据存储:仿冒 SqlClient(T-SQL 转写成 SQLite)、数据库页面、DataGridView、DateTimePicker
- 每个学生一套数据库,长期保存(data/databases/<用户编号>/库名.db);学生程序运行时挂进沙箱可读写 - Sim.Data:SqlConnection / SqlCommand / SqlDataReader / SqlDataAdapter / SqlCommandBuilder / SqlParameter; 连接字符串只按库名打开学生自己的库;ScriptDom 解析 T-SQL 后按白名单转写成 SQLite 语句, STRICT 表 + 元数据表还原 SQL Server 的列类型,报错编号和中文信息与 SQL Server 一致; INSERT 不写列名时跳过自增列,日期统一格式(书上 DateTime.ToString() 拼接的日期能正确比较) - 常驻 SQL 服务(Sim.Runner sql-server):数据库页面的查询、对象资源管理器,评分前按实验 database.sql 建库 - 数据库页面(代替 SSMS):对象资源管理器、查询窗口、编辑前 200 行、表设计器、恢复实验初始数据 - DataGridView(绑定 DataView/DataTable/DataSet,单元格修改写回 DataTable)、DateTimePicker;设计器工具箱加入 - 评分:每个检查项一份新建的实验库;新增点 / 修改表格单元格、选日期、表格里有 / 没有某行的检查 - 示例:项目 6 任务 2、3;时间格式改成和中文 Windows 一致(9:05:03);异常堆栈不暴露服务器路径 - 测试:数据库端到端、接口(每人只看到自己的库、恢复实验数据)、评分出错情况、T-SQL 生成 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
6b088240da
commit
670abe5921
72 files changed
+7253
-51
No files matched your search
+12
-3
@@ -167,6 +167,7 @@ IOT/
|
||||
| 后端 | 参数校验 | 计划:Zod |
|
||||
| C# 运行时 | 平台 | .NET 10 LTS |
|
||||
| C# 运行时 | 编译 | Roslyn,常驻编译服务,内存编译,中文报错;编译时改写旧版线程 API(Suspend / Resume / Abort) |
|
||||
| C# 运行时 | 数据库 | 仿冒 System.Data.SqlClient(`Sim.Data`):Microsoft.Data.Sqlite + ScriptDom(T-SQL 解析);常驻 SQL 服务供数据库页面使用 |
|
||||
| C# 运行时 | 运行器 | .NET 控制台程序,模拟界面线程和消息循环 |
|
||||
| C# 运行时 | 仿真类库 | 自研:`System.Windows.Forms` 子集 + 教材设备类库 + `Font` 等少量 System.Drawing 类型 |
|
||||
| C# 运行时 | 数据库仿真 | 计划:仿冒 `System.Data.SqlClient`,底层 Microsoft.Data.Sqlite;T-SQL 用 ScriptDom 解析后转写 |
|
||||
@@ -212,7 +213,7 @@ IOT/
|
||||
| 3 智慧路灯 | ZigBee 开关路灯;人体红外每 5 秒检测并联动路灯 | Lamp 控件、zigBeeHelper、adam4150Helper、CheckBox、RadioButton、Timer | 已完成 |
|
||||
| 4 入侵监测 | 红外对射检测;网络摄像机画面与云台;报警灯 | PictureBox、摄像头仿真、Alarm 控件、图片保存 | 已完成 |
|
||||
| 5 灾情监测 | 火焰(Timer)、烟雾(Thread)、灾情记录与推送 | Thread(含 Suspend / Resume / Abort)、跨线程改界面、ListBox、FormClosing | 已完成 |
|
||||
| 6 数据存储 | 建库建表、采集入库与增删改、按时间段查询 | SQL 窗口(代替 SSMS)、SqlClient 仿冒(SQLite)、DataGridView、DateTimePicker | |
|
||||
| 6 数据存储 | 建库建表、采集入库与增删改、按时间段查询 | SQL 窗口(代替 SSMS)、SqlClient 仿冒(SQLite)、DataGridView、DateTimePicker | 已完成 |
|
||||
| 7 情景控制 | 智慧教室、寝室、会议室三种情景联动 | TrackBar、资源图片、PictureBox 当按钮、mp3 播放、虚拟时钟 | |
|
||||
| 8 管理平台 | 主界面、校园环境(自动控制、7 天温度图表)、校园安防(抓拍入库、历史图片) | Panel Dock、无边框窗体、透明背景、Chart、ShowDialog、图片存数据库 | |
|
||||
|
||||
@@ -236,7 +237,7 @@ flowchart TB
|
||||
P0["阶段 0 · 技术验证(已完成 2026-10-22)<br/>教材项目 2 任务 1 原样运行;实测编译、延迟、内存"]
|
||||
P1["阶段 1 · MVP(进行中,约 3 个月)<br/>虚拟实训台 ✔、代码编辑器 ✔、窗体设计器 ✔、多窗体 ✔<br/>教材示例:项目 1–3 全部 ✔,项目 4–5 中平台已支持的 3 个任务 ✔<br/>部署(沙箱、Docker Compose、GitHub Actions)✔"]
|
||||
P2["阶段 2 · 教学闭环(进行中,约 2 个月)<br/>账号与班级 ✔、作品保存在服务器 ✔、自动评分 ✔、布置与提交作业 ✔<br/>评阅(看代码、运行、老师评分、评语)✔、成绩表与导出 ✔;一个班试用"]
|
||||
P3["阶段 3 · 扩展(进行中)<br/>教材项目 4–8:摄像头 ✔、线程 ✔、SQLite 模拟数据库、图表、虚拟时钟"]
|
||||
P3["阶段 3 · 扩展(进行中)<br/>教材项目 4–8:摄像头 ✔、线程 ✔、SQLite 模拟数据库 ✔、图表、虚拟时钟"]
|
||||
P4["阶段 4 · 进阶(之后)<br/>校园街景场景、故障注入题库、导出 VS 工程"]
|
||||
P0 -->|"关口:链路跑通,延迟和资源占用可接受"| P1
|
||||
P1 -->|"关口:教材项目 1–3 能在平台上完整做完"| P2
|
||||
@@ -282,6 +283,14 @@ flowchart TB
|
||||
|
||||
- 2026-10-22:项目 4 任务 2 网络摄像机,至此教材项目 1–5 全部完成(13 个示例)。摄像头画面是自绘的扁平插画(`runtime/Sim.Devices/Camera/scene.svg`,从校园里望向东围墙,墙头装着红外对射),按云台位置(左右 7 档、上下 3 档)切成 640×480 的 JPEG 帧;`PanUp` 等每次转一格,实训台红外对射被遮挡时画面里出现翻墙的人、光束断开,为书上"发现入侵自动抓拍"的探究题准备。`ipCameraHelper` 的类名、委托名(`CameraImage`)、事件参数(`ImageReadEvenArgs.img`)与教材 dll 一致,和仿真版一样每 250 ms 在后台线程上触发 `ImageRead`,书上不用 Invoke 直接给 `pictureBox1.Image` 赋值也能显示。`Image` / `Bitmap` 保存真实的图片数据:`Image.Save` 写出能打开的 jpg,`FromFile` / `FromStream` 读回,文件夹不存在时和 GDI+ 一样报"一般性错误"。图片数据每张只发给浏览器一次(按内容哈希缓存),之后控件属性里只带编号;同一位置的画面复用同一个对象,画面不变时不产生消息。学生程序的"程序所在目录"(`AppDomain.CurrentDomain.BaseDirectory`,编译检查单独放行)和当前目录都指向可写的 bin/Debug(沙箱里在沙箱自己的临时目录),程序结束后清掉;`Image.Save` 保存的图片显示在运行区的照片列表里,点开看大图,下次运行时清空。新增 PictureBox(SizeMode 五种、BorderStyle),设计器工具箱加"图片框";评分规则加"图片框显示了图片""摄像头开启 / 关闭 / 朝某方向转过""保存了图片"三种检查。
|
||||
|
||||
- 2026-10-23:项目 6 数据存储(3 个任务)。**每个学生一套数据库,长期保存**(`data/databases/<用户编号>/库名.db`,每个库一个 SQLite 文件,最多 20 个库、每个约 50 MB),就像自己电脑上的 SQL Server:任务 1 建的库、任务 2 存的数据,任务 3 能查到。
|
||||
- **SqlClient 仿冒**(`runtime/Sim.Data`):SqlConnection / SqlCommand / SqlDataReader / SqlDataAdapter / SqlCommandBuilder / SqlParameter,DataSet、DataTable、DataView 直接用 .NET 自带的。连接字符串只按 Initial Catalog 打开学生自己的同名库(服务器名、账号密码不检查,书上的长服务器名、"." 都能连上),库不存在时报 4060。
|
||||
- **T-SQL 转写**:ScriptDom(SQL Server 2008 语法)解析后按白名单逐个节点转写成 SQLite 语句,不认识的语法报"平台暂不支持",生成的 SQL 里只有平台写出的关键字和 tsql_ 函数。表用 STRICT 模式保存,原始的 T-SQL 列类型记在元数据表里,读出时还原成 SQL Server 返回的 .NET 类型(int、DateTime、bool……);varchar(n) 超长、类型不对、NULL、重复主键都报和 SQL Server 一样的错误号和中文信息。`insert into 表 values (...)` 不写列名时跳过自增列(照书上写时值的顺序和列顺序不一致,数据会存进错的列,和真实情况一样);日期统一存成 yyyy-MM-dd HH:mm:ss,书上拼接的 `DateTime.Now.ToString()`(2024/1/16 9:05:03)在插入和 BETWEEN 比较时都转换;支持 TOP(含 UPDATE / DELETE TOP)、CONVERT 样式 120 等、year / getdate / dateadd / datediff、`+` 按类型连接或相加、参数化查询、@@IDENTITY、多条语句。SqlCommandBuilder 根据带中文别名的查询生成 UPDATE。
|
||||
- **DataGridView**:绑定 DataView / DataTable / DataSet,自动生成列;在单元格里修改的值写回 DataTable,配合 SqlDataAdapter.Update 保存;当前行 ▶、新增行 *、选中行、CurrentRow.Cells[0].Value;类型转换失败时和 WinForms 一样触发 DataError。**DateTimePicker**:Long / Short / Time / Custom 格式与中文 Windows 一致,弹出浏览器的日期选择框。设计器工具箱加"数据表格""日期时间选择器"。
|
||||
- **数据库页面**(代替 SSMS,`/database`):对象资源管理器(库 → 表 → 列,右键新建数据库、新建表、设计、选择前 1000 行、编辑前 200 行、删除);查询窗口(F5 执行、选中部分只执行选中的、USE 切换库,结果网格和消息栏的格式与 SSMS 一致,每批最多 5 秒);编辑前 200 行(改单元格即 UPDATE、* 行新增、右键删除,没有主键的表按所有列的原值定位);表设计器(列名、类型、允许 Null、右键设主键、标识列,"查看 SQL 脚本"显示对应的 CREATE TABLE);"恢复实验初始数据"按实验的 `database.sql` 替换实验用到的库,其他库不动。这些操作都生成 T-SQL 交给常驻的 SQL 服务执行,和学生程序走同一套转写。
|
||||
- **评分**:每个实验可以带 `database.sql`,评分时每个检查项用一份新建的实验库,不碰学生自己的数据;评分规则加"点 / 修改表格单元格""在日期时间选择器里选日期""表格里有 / 没有某行"。新增示例项目 6 任务 2、3(任务 1 在数据库页面上完成),共 15 个。
|
||||
- 实测:用到数据库的学生程序比不用的多约 11 MB 内存(PSS 17 → 28 MB)。另外修正了平台上的时间格式:Linux 的中文区域数据是 09:05:03,改成和中文 Windows 一样的 9:05:03。
|
||||
|
||||
**其他改进**:
|
||||
|
||||
- 2026-10-22:代码编辑器的语言功能:代码补全(输入 `btn_Open.` 列出按钮的属性、方法、事件,只列出平台仿真了的成员)、悬停提示、参数提示(`MessageBox.Show(` 列出重载,标出正在填的参数)、停止输入 1 秒后自动检查编译错误(提示和点"运行"时一样)。语言服务是一个常驻进程,每个浏览器标签页一份工程,只更新有变化的文件。实测(限制 2 核):50 个标签页同时检查 1.2 秒内全部完成,同时补全 0.7 秒;内存约 260 MB。
|
||||
@@ -296,7 +305,7 @@ flowchart TB
|
||||
| 仿真 WinForms 工作量 | 项目 4–8 需要的控件和窗体特性较多 | 按项目逐步实现;项目 1–3 只需约 10 种控件 |
|
||||
| 事件顺序保真 | 书上代码依赖真实 WinForms 的事件顺序:单选按钮先触发"取消选中"再触发"选中",ComboBox 的 Click 先于展开,CheckBox 的 Click 时 Checked 已切换 | 逐项对照真实行为实现,并用书上代码做回归测试(单选、复选、下拉已实现并有测试) |
|
||||
| 书与配套不一致 | 控件名、步骤在书、表格和配套工程之间经常不同,书上代码有编译错误 | 以书为准逐任务整理模板和修正版答案 |
|
||||
| T-SQL 转 SQLite | 教材用 SQL Server 写法(`TOP`、`CONVERT`、DataAdapter 回写、日期字符串) | 用 ScriptDom 解析后转写;连接串一律指向学生自己的 SQLite 库;日期统一存为标准格式;以教材全部 SQL 语句为测试集 |
|
||||
| T-SQL 转 SQLite | 教材用 SQL Server 写法(`TOP`、`CONVERT`、DataAdapter 回写、日期字符串) | 已实现:ScriptDom 解析后按白名单转写;连接串只按库名打开学生自己的库;日期统一存为标准格式;STRICT 表和 CHECK 约束让类型、长度错误和 SQL Server 一样报出 |
|
||||
| 旧版线程 API | `Thread.Suspend` / `Resume` / `Abort` 在新版 .NET 上会报错 | 已实现:编译时改写成平台的协作式实现,被挂起或终止的线程在 Sleep、改控件、调设备类库时停下 |
|
||||
| 图片处理 | System.Drawing 在 Linux 上不受支持 | 已实现:自己的 `Image` / `Bitmap` 只保存图片文件数据和尺寸,能显示、保存、读回,不能逐像素绘制 |
|
||||
| 时间相关逻辑 | 项目 3 起就有按时刻开关灯的练习,部分定时器间隔长达 2 小时 | 提供可调、可加速的虚拟时钟 |
|
||||
|
||||
Reference in new issue
Block a user