175 lines
4.9 KiB
Markdown
175 lines
4.9 KiB
Markdown
# qfod_record 实体
|
||
|
||
> 所属模块:[数据模型概览](../概览.md)
|
||
|
||
---
|
||
|
||
## 1. 表定义
|
||
|
||
**表名**:`qfod_record`
|
||
|
||
**描述**:存储 Qfod 格式解析数据,对应日志格式 `X#:Q A->B C D E`
|
||
|
||
---
|
||
|
||
## 2. 字段定义
|
||
|
||
| 列名 | 类型 | 约束 | 说明 |
|
||
|------|------|------|------|
|
||
| id | UUID | PK, NOT NULL | 主键 |
|
||
| scenario_id | UUID | FK, NOT NULL | 关联测试场景 |
|
||
| charger_index | TINYINT | NOT NULL | 充电器索引(0 或 1) |
|
||
| coil_index | TINYINT | NOT NULL | 线圈索引(0、1、2) |
|
||
| delta_q | INT | NOT NULL | Q值变化量(ΔQ = current_q - raw_q) |
|
||
| current_q | FLOAT | NOT NULL | 当前实时 Q值 |
|
||
| raw_q | FLOAT | NOT NULL | 原始 Q值 |
|
||
| fod_type | TINYINT | NOT NULL | 异物类型编码 |
|
||
| is_deleted | BOOLEAN | NOT NULL, DEFAULT FALSE | 软删除标记 |
|
||
| created_at | TIMESTAMP | NOT NULL, DEFAULT NOW() | 创建时间 |
|
||
|
||
---
|
||
|
||
## 3. 外键
|
||
|
||
| 外键 | 引用表 | 说明 |
|
||
|------|--------|------|
|
||
| scenario_id | test_scenario.id | 关联测试场景(必需) |
|
||
|
||
---
|
||
|
||
## 4. 索引
|
||
|
||
| 索引名 | 字段 | 用途 |
|
||
|--------|------|------|
|
||
| idx_qfod_scenario | scenario_id | 按测试场景查询 |
|
||
| idx_qfod_charger_coil | (charger_index, coil_index) | 按检测通道查询 |
|
||
| idx_qfod_fod_type | fod_type | 按异物类型统计 |
|
||
| idx_qfod_delta_q | delta_q | 阈值分析 |
|
||
|
||
---
|
||
|
||
## 5. 约束
|
||
|
||
| 约束名 | 类型 | 定义 |
|
||
|--------|------|------|
|
||
| chk_qfod_charger | CHECK | charger_index IN (0, 1) |
|
||
| chk_qfod_coil | CHECK | coil_index IN (0, 1, 2) |
|
||
|
||
> **数据库兼容性**:`IN (0, 1)` 语法在 SQLite、PostgreSQL、MySQL 中均可使用。若使用其他数据库,需验证 CHECK 约束语法兼容性。
|
||
|
||
---
|
||
|
||
## 6. EF Core 模型
|
||
|
||
### 实体类
|
||
|
||
```csharp
|
||
// Models/QfodRecord.cs
|
||
namespace WCTDataMiner.Models;
|
||
|
||
public class QfodRecord
|
||
{
|
||
public Guid Id { get; set; } = Guid.NewGuid();
|
||
public Guid ScenarioId { get; set; }
|
||
public byte ChargerIndex { get; set; }
|
||
public byte CoilIndex { get; set; }
|
||
public int DeltaQ { get; set; }
|
||
public float CurrentQ { get; set; }
|
||
public float RawQ { get; set; }
|
||
public byte FodType { get; set; }
|
||
public bool IsDeleted { get; set; } = false;
|
||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||
|
||
// Navigation Properties
|
||
public TestScenario Scenario { get; set; } = null!;
|
||
}
|
||
```
|
||
|
||
### 配置类
|
||
|
||
```csharp
|
||
// Data/Configurations/QfodRecordConfiguration.cs
|
||
using Microsoft.EntityFrameworkCore;
|
||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||
using WCTDataMiner.Models;
|
||
|
||
namespace WCTDataMiner.Data.Configurations;
|
||
|
||
public class QfodRecordConfiguration : IEntityTypeConfiguration<QfodRecord>
|
||
{
|
||
public void Configure(EntityTypeBuilder<QfodRecord> builder)
|
||
{
|
||
builder.ToTable("qfod_record");
|
||
|
||
builder.HasKey(e => e.Id);
|
||
builder.Property(e => e.Id).HasColumnName("id");
|
||
|
||
builder.Property(e => e.ScenarioId)
|
||
.IsRequired()
|
||
.HasColumnName("scenario_id");
|
||
|
||
builder.Property(e => e.ChargerIndex)
|
||
.IsRequired()
|
||
.HasColumnName("charger_index");
|
||
|
||
builder.Property(e => e.CoilIndex)
|
||
.IsRequired()
|
||
.HasColumnName("coil_index");
|
||
|
||
builder.Property(e => e.DeltaQ)
|
||
.IsRequired()
|
||
.HasColumnName("delta_q");
|
||
|
||
builder.Property(e => e.CurrentQ)
|
||
.IsRequired()
|
||
.HasColumnName("current_q");
|
||
|
||
builder.Property(e => e.RawQ)
|
||
.IsRequired()
|
||
.HasColumnName("raw_q");
|
||
|
||
builder.Property(e => e.FodType)
|
||
.IsRequired()
|
||
.HasColumnName("fod_type");
|
||
|
||
builder.Property(e => e.IsDeleted)
|
||
.IsRequired()
|
||
.HasDefaultValue(false)
|
||
.HasColumnName("is_deleted");
|
||
|
||
builder.Property(e => e.CreatedAt)
|
||
.IsRequired()
|
||
.HasDefaultValueSql("NOW()")
|
||
.HasColumnName("created_at");
|
||
|
||
// 索引
|
||
builder.HasIndex(e => e.ScenarioId).HasDatabaseName("idx_qfod_scenario");
|
||
builder.HasIndex(e => new { e.ChargerIndex, e.CoilIndex }).HasDatabaseName("idx_qfod_charger_coil");
|
||
builder.HasIndex(e => e.FodType).HasDatabaseName("idx_qfod_fod_type");
|
||
builder.HasIndex(e => e.DeltaQ).HasDatabaseName("idx_qfod_delta_q");
|
||
|
||
// CHECK 约束
|
||
builder.HasCheckConstraint("chk_qfod_charger", "charger_index IN (0, 1)");
|
||
builder.HasCheckConstraint("chk_qfod_coil", "coil_index IN (0, 1, 2)");
|
||
|
||
// 关系配置
|
||
builder.HasOne(e => e.Scenario)
|
||
.WithMany(e => e.QfodRecords)
|
||
.HasForeignKey(e => e.ScenarioId)
|
||
.IsRequired();
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 7. 检测通道组合
|
||
|
||
| ChargerIndex | CoilIndex | 检测通道 |
|
||
|--------------|-----------|----------|
|
||
| 0 | 0 | 充电器0-线圈0 |
|
||
| 0 | 1 | 充电器0-线圈1 |
|
||
| 0 | 2 | 充电器0-线圈2 |
|
||
| 1 | 0 | 充电器1-线圈0 |
|
||
| 1 | 1 | 充电器1-线圈1 |
|
||
| 1 | 2 | 充电器1-线圈2 | |