119 lines
4.0 KiB
C#
119 lines
4.0 KiB
C#
using Entities.Contracts;
|
||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||
using Microsoft.EntityFrameworkCore;
|
||
|
||
namespace TechHelper.Context.Configuration
|
||
{
|
||
public class QuestionConfiguration : IEntityTypeConfiguration<Question>
|
||
{
|
||
public void Configure(EntityTypeBuilder<Question> builder)
|
||
{
|
||
// 1. 设置表名
|
||
builder.ToTable("questions");
|
||
|
||
// 2. 设置主键
|
||
builder.HasKey(q => q.Id);
|
||
|
||
builder.HasIndex(q => q.Title)
|
||
.HasPrefixLength(20);
|
||
|
||
// 3. 配置列名、必需性、长度及其他属性
|
||
|
||
// Id
|
||
builder.Property(q => q.Id)
|
||
.HasColumnName("id");
|
||
// 对于 Guid 类型的主键,EF Core 默认由应用程序生成值,无需 ValueGeneratedOnAdd()
|
||
|
||
|
||
// QuestionText
|
||
builder.Property(q => q.Title)
|
||
.HasColumnName("question_text")
|
||
.IsRequired()
|
||
.HasMaxLength(65535); // 对应 MaxLength(65535)
|
||
|
||
// QuestionType (枚举作为字符串存储)
|
||
builder.Property(q => q.Type)
|
||
.HasColumnName("question_type")
|
||
.IsRequired()
|
||
.HasMaxLength(20);
|
||
|
||
// CorrectAnswer
|
||
builder.Property(q => q.Answer)
|
||
.HasColumnName("correct_answer")
|
||
.HasMaxLength(65535);
|
||
|
||
// DifficultyLevel (枚举作为字符串存储)
|
||
builder.Property(q => q.DifficultyLevel)
|
||
.HasColumnName("difficulty_level")
|
||
.HasMaxLength(10);
|
||
|
||
|
||
// SubjectArea
|
||
builder.Property(q => q.SubjectArea)
|
||
.HasColumnName("subject_area")
|
||
.HasMaxLength(100);
|
||
|
||
// CreatedBy
|
||
builder.Property(q => q.CreatorId)
|
||
.HasColumnName("created_by")
|
||
.IsRequired();
|
||
|
||
// CreatedAt (自动在添加时设置)
|
||
builder.Property(q => q.CreatedAt)
|
||
.HasColumnName("created_at")
|
||
.IsRequired() // 通常创建时间是必需的
|
||
.ValueGeneratedOnAdd(); // EF Core 在实体添加时自动设置值
|
||
|
||
// UpdatedAt (自动在添加或更新时设置,并作为并发令牌)
|
||
builder.Property(q => q.UpdatedAt)
|
||
.HasColumnName("updated_at")
|
||
.IsRequired() // 通常更新时间是必需的
|
||
.ValueGeneratedOnAddOrUpdate() // EF Core 在实体添加或更新时自动设置值
|
||
.IsConcurrencyToken(); // 用作乐观并发令牌,防止数据冲突
|
||
|
||
// IsDeleted (软删除标记,默认 false)
|
||
builder.Property(q => q.IsDeleted)
|
||
.HasColumnName("deleted")
|
||
.HasDefaultValue(false);
|
||
|
||
// 4. 配置导航属性和外键关系
|
||
|
||
// ---
|
||
// 配置 Question 到 User (Creator) 的关系 (多对一)
|
||
// 一个 Question 由一个 User (Creator) 创建。
|
||
//
|
||
// 假设 `User` 实体中有一个名为 `CreatedQuestions` 的 `ICollection<Question>` 集合属性。
|
||
builder.HasOne(q => q.Creator) // 当前 Question 有一个 Creator
|
||
.WithMany(u => u.CreatedQuestions) // 那个 Creator 可以创建多个 Question
|
||
.HasForeignKey(q => q.CreatorId) // 外键是 Question.CreatedBy
|
||
.OnDelete(DeleteBehavior.Restrict); // 当 User (Creator) 被删除时,如果还有他/她创建的 Question,则会阻止删除。
|
||
// 由于 CreatedBy 是 [Required],Prevent/Restrict 是一个安全的选择。
|
||
|
||
// ---
|
||
// 配置 Question 到 AssignmentQuestion 的关系 (一对多)
|
||
// 一个 Question 可以被多个 AssignmentQuestion 引用。
|
||
//
|
||
// 这个关系的外键配置通常在 "多" 的一方(`AssignmentQuestion` 实体)进行。
|
||
// 假设 `AssignmentQuestion` 实体有一个 `QuestionId` 外键和 `Question` 导航属性。
|
||
builder.HasMany(q => q.AssignmentQuestions) // 当前 Question 有多个 AssignmentQuestion
|
||
.WithOne(aq => aq.Question); // 每一个 AssignmentQuestion 都有一个 Question
|
||
// .HasForeignKey(aq => aq.QuestionId); // 外键的配置应在 `AssignmentQuestionConfiguration` 中进行
|
||
|
||
|
||
builder.HasOne(q => q.KeyPoint)
|
||
.WithMany(kp => kp.Questions)
|
||
.HasForeignKey(q => q.KeyPointId)
|
||
.OnDelete(DeleteBehavior.SetNull);
|
||
|
||
builder.HasOne(q => q.Lesson)
|
||
.WithMany(kp => kp.Questions)
|
||
.IsRequired(false)
|
||
.HasForeignKey(q => q.LessonId)
|
||
.OnDelete(DeleteBehavior.SetNull);
|
||
|
||
|
||
}
|
||
}
|
||
}
|
||
|