重构试卷相关内容

This commit is contained in:
SpecialX
2025-06-13 19:01:32 +08:00
parent b77ed0b30f
commit bcf351ff25
23 changed files with 980 additions and 84 deletions

View File

@@ -0,0 +1,111 @@
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Microsoft.EntityFrameworkCore;
using Entities.Contracts;
namespace TechHelper.Server.Context.Configuration
{
public class QuestionGroupConfiguration : IEntityTypeConfiguration<QuestionGroup>
{
public void Configure(EntityTypeBuilder<QuestionGroup> builder)
{
// 1. 设置表名
builder.ToTable("question_groups");
// 2. 设置主键
builder.HasKey(qg => qg.Id);
// 3. 配置列属性
// Title 标题
builder.Property(qg => qg.Title)
.HasColumnName("title")
.HasMaxLength(255)
.IsRequired(false); // 允许为空
// Description 描述内容 (Required)
builder.Property(qg => qg.Description)
.HasColumnName("description")
.IsRequired()
.HasColumnType("longtext"); // 对应 MySQL 的 TEXT 或 LONGTEXT
// Type 类型 (例如: "ReadingComprehension", "DiagramAnalysis")
builder.Property(qg => qg.Type)
.HasColumnName("type")
.HasMaxLength(50)
.IsRequired(false); // 允许为空
// DifficultyLevel 难度级别 (枚举映射为字符串)
builder.Property(qg => qg.DifficultyLevel)
.HasColumnName("difficulty_level")
.HasConversion<string>() // 将枚举转换为字符串存储
.HasMaxLength(10);
// SubjectArea 科目领域 (枚举映射为字符串)
builder.Property(qg => qg.SubjectArea)
.HasColumnName("subject_area")
.HasConversion<string>(); // 将枚举转换为字符串存储
// TotalQuestions 包含题目总数
builder.Property(qg => qg.TotalQuestions)
.HasColumnName("total_questions")
.IsRequired();
// ParentQG 父题组 ID (外键,自引用关系)
builder.Property(qg => qg.ParentQG)
.HasColumnName("parent_question_group") // 使用你定义的列名
.IsRequired(false); // 可为空,因为根题组没有父级
// CreatedBy 创建者 ID (外键)
builder.Property(qg => qg.CreatedBy)
.HasColumnName("created_by")
.IsRequired();
// CreatedAt 创建时间
builder.Property(qg => qg.CreatedAt)
.HasColumnName("created_at")
.IsRequired();
// UpdatedAt 更新时间
builder.Property(qg => qg.UpdatedAt)
.HasColumnName("updated_at")
.IsRequired();
// IsDeleted 是否删除 (软删除)
builder.Property(qg => qg.IsDeleted)
.HasColumnName("deleted")
.IsRequired();
// ValidGroup 是否有效
builder.Property(qg => qg.ValidGroup)
.HasColumnName("valid_group")
.IsRequired();
// 4. 配置关系
// 与 User 的关系 (创建者)
builder.HasOne(qg => qg.Creator)
.WithMany()
.HasForeignKey(qg => qg.CreatedBy)
.OnDelete(DeleteBehavior.Restrict); // 阻止删除关联的 User
// 与 Question 的关系 (一对多)
// 一个 QuestionGroup 可以包含多个 Question
builder.HasMany(qg => qg.Questions)
.WithOne(q => q.QuestionGroup) // Question 实体中的 QuestionGroup 导航属性
.HasForeignKey(q => q.QuestionGroupId) // Question 实体中的 QuestionGroupId 外键
.IsRequired(false) // QuestionGroupId 在 Question 实体中是可空的
.OnDelete(DeleteBehavior.SetNull); // 如果 QuestionGroup 被删除,关联的 Question 的外键设置为 NULL
// 与自身的自引用关系 (父子题组)
// 一个 QuestionGroup 可以有多个 ChildQuestionGroups
builder.HasMany(qg => qg.ChildQuestionGroups)
.WithOne(childQG => childQG.ParentQuestionGroup) // 子 QuestionGroup 实体中的 ParentQuestionGroup 导航属性
.HasForeignKey(childQG => childQG.ParentQG) // 子 QuestionGroup 实体中的 ParentQG 外键
.IsRequired(false) // ParentQG 是可空的,因为根题组没有父级
.OnDelete(DeleteBehavior.Restrict); // 或者 SetNull, Cascade。Restrict 更安全,避免意外删除整个分支。
// 如果选择 SetNull删除父组时子组的 ParentQG 会变为 NULL它们就成了新的根组。
// 如果选择 Cascade删除父组会递归删除所有子组。根据业务逻辑选择。
// 这里我选择了 Restrict 作为默认安全选项。
}
}
}