Files
TechHelper/TechHelper.Server/Context/Configuration/QuestionGroupConfiguration.cs
2025-06-13 19:01:32 +08:00

112 lines
4.0 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 作为默认安全选项。
}
}
}