- 每个学生一套数据库,长期保存(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>
32 lines
1.2 KiB
C#
32 lines
1.2 KiB
C#
// 运行器与服务器之间的消息格式,对应 shared/protocol.ts,两边修改时要同步。
|
||
// 运行器 → 服务器的消息在各处用 JsonObject 直接构造;这里只集中定义从服务器收到的动作。
|
||
using System.Text.Json.Nodes;
|
||
|
||
namespace Sim.Host;
|
||
|
||
/// <summary>浏览器上报的用户操作(shared/protocol.ts 中的 UserAction)</summary>
|
||
public sealed class UserAction
|
||
{
|
||
public required string Action { get; init; }
|
||
public string? Value { get; init; }
|
||
public int Index { get; init; }
|
||
public string Button { get; init; } = "left";
|
||
public int X { get; init; }
|
||
public int Y { get; init; }
|
||
/// <summary>DataGridView 的单元格:行号、列号(-1 表示行标题)</summary>
|
||
public int Row { get; init; } = -1;
|
||
public int Column { get; init; } = -1;
|
||
|
||
public static UserAction FromJson(JsonObject json) => new()
|
||
{
|
||
Action = (string?)json["action"] ?? "",
|
||
Value = (string?)json["value"],
|
||
Index = (int?)json["index"] ?? -1,
|
||
Button = (string?)json["button"] ?? "left",
|
||
X = (int?)json["x"] ?? 0,
|
||
Y = (int?)json["y"] ?? 0,
|
||
Row = (int?)json["row"] ?? -1,
|
||
Column = (int?)json["column"] ?? -1,
|
||
};
|
||
}
|