重构项目结构,移除Assignment相关功能,优化Submission模块
Some checks failed
TechAct / explore-gitea-actions (push) Failing after 12s
Some checks failed
TechAct / explore-gitea-actions (push) Failing after 12s
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
using TechHelper.Context.Configuration;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Entities.Contracts;
|
||||
@@ -11,31 +10,29 @@ namespace TechHelper.Context
|
||||
public ApplicationContext(DbContextOptions options)
|
||||
: base(options) { }
|
||||
|
||||
public DbSet<AssignmentClass> AssignmentClasses { get; set; }
|
||||
public DbSet<Assignment> Assignments { get; set; }
|
||||
public DbSet<AssignmentQuestion> AssignmentQuestions { get; set; }
|
||||
public DbSet<School> Schools { get; set; }
|
||||
public DbSet<Grade> Grades { get; set; }
|
||||
public DbSet<Class> Classes { get; set; }
|
||||
public DbSet<ClassTeacher> ClassStudents { get; set; }
|
||||
public DbSet<ClassTeacher> ClassTeachers { get; set; }
|
||||
public DbSet<Exam> Exams { get; set; }
|
||||
public DbSet<ExamQuestion> ExamQuestions { get; set; }
|
||||
public DbSet<ExamAttachment> ExamAttachments{ get; set; }
|
||||
public DbSet<ExamType> ExamTypes { get; set; }
|
||||
public DbSet<Question> Questions { get; set; }
|
||||
public DbSet<Submission> Submissions { get; set; }
|
||||
public DbSet<SubmissionDetail> SubmissionDetails { get; set; }
|
||||
public DbSet<QuestionContext> QuestionContexts { get; set; }
|
||||
public DbSet<Global> Globals { get; set; }
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder builder)
|
||||
{
|
||||
base.OnModelCreating(builder);
|
||||
builder.ApplyConfiguration(new RoleConfiguration());
|
||||
builder.ApplyConfiguration(new AssignmentConfiguration());
|
||||
builder.ApplyConfiguration(new AssignmentClassConfiguration());
|
||||
builder.ApplyConfiguration(new AssignmentQuestionConfiguration());
|
||||
builder.ApplyConfiguration(new ClassConfiguration());
|
||||
builder.ApplyConfiguration(new ClassStudentConfiguration());
|
||||
builder.ApplyConfiguration(new ClassTeacherConfiguration());
|
||||
builder.ApplyConfiguration(new QuestionConfiguration());
|
||||
builder.ApplyConfiguration(new SubmissionConfiguration());
|
||||
builder.ApplyConfiguration(new SubmissionDetailConfiguration());
|
||||
}
|
||||
//protected override void OnModelCreating(ModelBuilder builder)
|
||||
//{
|
||||
// base.OnModelCreating(builder);
|
||||
// builder.ApplyConfiguration(new RoleConfiguration());
|
||||
// builder.ApplyConfiguration(new AssignmentConfiguration());
|
||||
// builder.ApplyConfiguration(new AssignmentClassConfiguration());
|
||||
// builder.ApplyConfiguration(new AssignmentQuestionConfiguration());
|
||||
// builder.ApplyConfiguration(new ClassConfiguration());
|
||||
// builder.ApplyConfiguration(new QuestionConfiguration());
|
||||
// builder.ApplyConfiguration(new SubmissionConfiguration());
|
||||
// builder.ApplyConfiguration(new SubmissionDetailConfiguration());
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
using AutoMapper;
|
||||
using AutoMapper.Internal.Mappers;
|
||||
using Entities.Contracts;
|
||||
using Entities.DTO;
|
||||
using Newtonsoft.Json;
|
||||
using System.Net.Http.Json;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using Entities.DTO.Class;
|
||||
|
||||
namespace TechHelper.Context
|
||||
{
|
||||
@@ -28,53 +24,91 @@ namespace TechHelper.Context
|
||||
{
|
||||
CreateMap<UserForRegistrationDto, User>()
|
||||
.ForMember(dest => dest.Id, opt => opt.Ignore())
|
||||
.ForMember(dest => dest.UserName, opt => opt.MapFrom(src => src.Name))
|
||||
.ForMember(dest => dest.UserName, opt => opt.MapFrom(src => src.DisplayName))
|
||||
.ForMember(dest => dest.Email, opt => opt.MapFrom(src => src.Email))
|
||||
.ForMember(dest => dest.PhoneNumber, opt => opt.MapFrom(src => src.PhoneNumber))
|
||||
.ForMember(dest => dest.Address, opt => opt.MapFrom(src => src.HomeAddress))
|
||||
.ForMember(dest => dest.HomeAddress, opt => opt.MapFrom(src => src.HomeAddress))
|
||||
.ForMember(dest => dest.PasswordHash, opt => opt.Ignore())
|
||||
.ForMember(dest => dest.EmailConfirmed, opt => opt.Ignore());
|
||||
|
||||
CreateMap<ClassDto, Class>()
|
||||
.ForMember(d => d.Number, o => o.MapFrom(src => src.Class))
|
||||
.ReverseMap();
|
||||
// Subject
|
||||
CreateMap<Subject, SubjectDto>().ReverseMap();
|
||||
CreateMap<Subject, SubjectResponseDto>().ReverseMap();
|
||||
CreateMap<Subject, TypeCommonDto>().ReverseMap();
|
||||
|
||||
// ExamType
|
||||
CreateMap<ExamType, ExamTypeDto>().ReverseMap();
|
||||
CreateMap<ExamType, TypeCommonDto>().ReverseMap();
|
||||
|
||||
// QuestionType
|
||||
CreateMap<QuestionType, QuestionTypeDto >().ReverseMap();
|
||||
CreateMap<QuestionType, TypeCommonDto>().ReverseMap();
|
||||
|
||||
|
||||
// Exam
|
||||
CreateMap<ExamDto, Exam>().ReverseMap();
|
||||
CreateMap<Exam, ExamListDto>().ReverseMap();
|
||||
|
||||
// Assignment
|
||||
CreateMap<AssignmentDto, Assignment>().ReverseMap();
|
||||
|
||||
CreateMap<AssignmentQuestionDto, AssignmentQuestion>().ReverseMap();
|
||||
CreateMap<ExamQuestionDto, ExamQuestion>().ReverseMap();
|
||||
|
||||
CreateMap<QuestionDto, Question>().ReverseMap();
|
||||
|
||||
CreateMap<QuestionContext, QuestionContextDto>().ReverseMap();
|
||||
|
||||
|
||||
|
||||
|
||||
// Submission
|
||||
CreateMap<SubmissionDto, Submission>().ReverseMap();
|
||||
|
||||
CreateMap<SubmissionDetailDto, SubmissionDetail>().ReverseMap();
|
||||
CreateMap<SubmissionTeacherUpdateDto, Submission>().ReverseMap();
|
||||
|
||||
// Student Submission Detail
|
||||
CreateMap<Submission, StudentSubmissionDetailDto>()
|
||||
.ForMember(dest => dest.AssignmentId, opt => opt.MapFrom(src => src.AssignmentId))
|
||||
.ForMember(dest => dest.AssignmentId, opt => opt.MapFrom(src => src.ExamId))
|
||||
.ForMember(dest => dest.StudentId, opt => opt.MapFrom(src => src.StudentId))
|
||||
.ForMember(dest => dest.SubmissionTime, opt => opt.MapFrom(src => src.SubmissionTime))
|
||||
.ForMember(dest => dest.OverallGrade, opt => opt.MapFrom(src => src.OverallGrade))
|
||||
.ForMember(dest => dest.OverallFeedback, opt => opt.MapFrom(src => src.OverallFeedback))
|
||||
.ForMember(dest => dest.Status, opt => opt.MapFrom(src => src.Status));
|
||||
|
||||
CreateMap<Assignment, AssignmentDto>().ReverseMap();
|
||||
CreateMap<Submission, SubmissionListDto>().ReverseMap();
|
||||
CreateMap<SubmissionDetail, SubmissionDetailTeacherUpdateDto>().ReverseMap();
|
||||
|
||||
|
||||
CreateMap<SubjectTypeMetadataDto, Global>()
|
||||
.ForMember(dest => dest.Info, opt => opt.MapFrom(src => JsonConvert.SerializeObject(src.Data)));
|
||||
CreateMap<Global, SubjectTypeMetadataDto>()
|
||||
.ForMember(dest => dest.Data, opt => opt.MapFrom(src => JsonConvert.DeserializeObject<Dictionary<string, (string Color, string DisplayName)>>(src.Info)));
|
||||
// School
|
||||
CreateMap<SchoolDto, School>().ReverseMap();
|
||||
CreateMap<SchoolResponseDto, School>().ReverseMap();
|
||||
|
||||
// Grade
|
||||
CreateMap<GradeDto, Grade>().ReverseMap();
|
||||
CreateMap<CreateGradeDto, Grade>().ReverseMap();
|
||||
|
||||
|
||||
// Class
|
||||
CreateMap<ClassDto, Class>().ReverseMap();
|
||||
CreateMap<ClassCreateDto, Class>().ReverseMap();
|
||||
|
||||
|
||||
// User
|
||||
CreateMap<User, UserDto>().ReverseMap();
|
||||
CreateMap<User, UserListDto>().ReverseMap();
|
||||
|
||||
// KeyPoint
|
||||
CreateMap<KeyPoint, KeyPointDto>().ReverseMap();
|
||||
CreateMap<KeyPoint, CreateKeyPointDto>().ReverseMap();
|
||||
CreateMap<KeyPoint, UpdateKeyPointDto>().ReverseMap();
|
||||
CreateMap<KeyPoint, KeyPointResponseDto>().ReverseMap();
|
||||
|
||||
// Lesson
|
||||
CreateMap<Lesson, LessonDto>().ReverseMap();
|
||||
CreateMap<Lesson, CreateLessonDto>().ReverseMap();
|
||||
CreateMap<Lesson, UpdateLessonDto>().ReverseMap();
|
||||
CreateMap<Lesson, LessonResponseDto>().ReverseMap();
|
||||
|
||||
// Textbook
|
||||
CreateMap<Textbook, TextbookDto>().ReverseMap();
|
||||
CreateMap<Textbook, CreateTextbookDto>().ReverseMap();
|
||||
CreateMap<Textbook, UpdateTextbookDto>().ReverseMap();
|
||||
CreateMap<Textbook, TextbookResponseDto>()
|
||||
.ForMember(dest => dest.LessonCount, opt => opt.MapFrom(src => src.Lessons.Count))
|
||||
.ForMember(dest => dest.LessonTitles, opt => opt.MapFrom(src => src.Lessons.Select(l => l.Title).ToList()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace TechHelper.Context.Configuration
|
||||
{
|
||||
public class AssignmentAttachmentConfiguration : IEntityTypeConfiguration<AssignmentAttachment>
|
||||
public class AssignmentAttachmentConfiguration : IEntityTypeConfiguration<ExamAttachment>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<AssignmentAttachment> builder)
|
||||
public void Configure(EntityTypeBuilder<ExamAttachment> builder)
|
||||
{
|
||||
builder.ToTable("assignment_attachments");
|
||||
|
||||
@@ -38,8 +38,8 @@ namespace TechHelper.Context.Configuration
|
||||
.HasDefaultValue(false);
|
||||
|
||||
// Configure the relationship explicitly
|
||||
builder.HasOne(aa => aa.Assignment) // An AssignmentAttachment has one Assignment
|
||||
.WithMany(a => a.AssignmentAttachments) // An Assignment has many AssignmentAttachments (assuming 'Attachments' collection in Assignment)
|
||||
builder.HasOne(aa => aa.Exam) // An AssignmentAttachment has one Assignment
|
||||
.WithMany(a => a.ExamAttachments) // An Assignment has many AssignmentAttachments (assuming 'Attachments' collection in Assignment)
|
||||
.HasForeignKey(aa => aa.AssignmentId) // The foreign key is AssignmentAttachment.AssignmentId
|
||||
.IsRequired() // It's a required relationship based on your [Required] attribute
|
||||
.OnDelete(DeleteBehavior.Cascade); // If an Assignment is deleted, its attachments should also be deleted
|
||||
|
||||
@@ -4,18 +4,18 @@ using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace TechHelper.Context.Configuration
|
||||
{
|
||||
public class AssignmentClassConfiguration : IEntityTypeConfiguration<AssignmentClass>
|
||||
public class AssignmentClassConfiguration : IEntityTypeConfiguration<ExamClass>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<AssignmentClass> builder)
|
||||
public void Configure(EntityTypeBuilder<ExamClass> builder)
|
||||
{
|
||||
// 设置表名为 "assignment_class"
|
||||
builder.ToTable("assignment_class");
|
||||
|
||||
// 设置复合主键
|
||||
builder.HasKey(ac => new { ac.AssignmentId, ac.ClassId });
|
||||
builder.HasKey(ac => new { ac.ExamId, ac.ClassId });
|
||||
|
||||
// 配置 AssignmentId 列名
|
||||
builder.Property(ac => ac.AssignmentId)
|
||||
builder.Property(ac => ac.ExamId)
|
||||
.HasColumnName("assignment_id");
|
||||
|
||||
// 配置 ClassId 列名
|
||||
@@ -34,15 +34,15 @@ namespace TechHelper.Context.Configuration
|
||||
|
||||
// 配置到 Assignment 的关系 (多对一)
|
||||
// 假设 Assignment 类中有一个名为 AssignmentClasses 的集合属性
|
||||
builder.HasOne(ac => ac.Assignment) // AssignmentClass 有一个 Assignment
|
||||
builder.HasOne(ac => ac.Exam) // AssignmentClass 有一个 Assignment
|
||||
.WithMany(a => a.AssignmentClasses) // Assignment 有多个 AssignmentClass 记录
|
||||
.HasForeignKey(ac => ac.AssignmentId) // 通过 AssignmentId 建立外键
|
||||
.HasForeignKey(ac => ac.ExamId) // 通过 AssignmentId 建立外键
|
||||
.OnDelete(DeleteBehavior.Cascade); // 当 Assignment 被删除时,相关的 AssignmentClass 记录也级联删除
|
||||
|
||||
// 配置到 Class 的关系 (多对一)
|
||||
// 假设 Class 类中有一个名为 AssignmentClasses 的集合属性
|
||||
builder.HasOne(ac => ac.Class) // AssignmentClass 有一个 Class
|
||||
.WithMany(c => c.AssignmentClasses) // Class 有多个 AssignmentClass 记录
|
||||
.WithMany(c => c.ExamClasses) // Class 有多个 AssignmentClass 记录
|
||||
.HasForeignKey(ac => ac.ClassId) // 通过 ClassId 建立外键
|
||||
.OnDelete(DeleteBehavior.Cascade); // 当 Class 被删除时,相关的 AssignmentClass 记录也级联删除
|
||||
}
|
||||
|
||||
@@ -5,9 +5,9 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace TechHelper.Context.Configuration
|
||||
{
|
||||
public class AssignmentConfiguration : IEntityTypeConfiguration<Assignment>
|
||||
public class AssignmentConfiguration : IEntityTypeConfiguration<Exam>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<Assignment> builder)
|
||||
public void Configure(EntityTypeBuilder<Exam> builder)
|
||||
{
|
||||
builder.ToTable("assignments");
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace TechHelper.Context.Configuration
|
||||
|
||||
builder.HasOne(a=>a.ExamStruct)
|
||||
.WithOne()
|
||||
.HasForeignKey<Assignment>(a=>a.ExamStructId)
|
||||
.HasForeignKey<Exam>(a=>a.ExamStructId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
}
|
||||
|
||||
@@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace TechHelper.Context.Configuration
|
||||
{
|
||||
public class AssignmentQuestionConfiguration : IEntityTypeConfiguration<AssignmentQuestion>
|
||||
public class AssignmentQuestionConfiguration : IEntityTypeConfiguration<ExamQuestion>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<AssignmentQuestion> builder)
|
||||
public void Configure(EntityTypeBuilder<ExamQuestion> builder)
|
||||
{
|
||||
// 1. 设置表名
|
||||
builder.ToTable("assignment_questions");
|
||||
@@ -44,13 +44,13 @@ namespace TechHelper.Context.Configuration
|
||||
|
||||
|
||||
builder.HasOne(aq => aq.Question)
|
||||
.WithMany(q => q.AssignmentQuestions)
|
||||
.WithMany(q => q.ExamQuestions)
|
||||
.HasForeignKey(aq => aq.QuestionId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder.HasOne(aq => aq.ParentAssignmentQuestion)
|
||||
builder.HasOne(aq => aq.ParentExamQuestion)
|
||||
.WithMany(aq => aq.ChildrenAssignmentQuestion)
|
||||
.HasForeignKey(aq => aq.ParentAssignmentQuestionId)
|
||||
.HasForeignKey(aq => aq.ParentExamQuestionId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder.HasOne(aq => aq.QuestionContext)
|
||||
|
||||
@@ -86,7 +86,7 @@ namespace TechHelper.Context.Configuration
|
||||
// 11. 与 AssignmentClass 的关系 (多对多中间表或一对多)
|
||||
// 一对多:一个 Class 有多个 AssignmentClass。一个 AssignmentClass 属于一个 Class。
|
||||
// 假设 AssignmentClass 有 'ClassId' 外键和 'Class' 导航属性。
|
||||
builder.HasMany(c => c.AssignmentClasses) // Class 中的集合导航属性
|
||||
builder.HasMany(c => c.ExamClasses) // Class 中的集合导航属性
|
||||
.WithOne(ac => ac.Class) // 假设 AssignmentClass 中有 'public Class Class { get; set; }'
|
||||
.HasForeignKey(ac => ac.ClassId) // 假设 AssignmentClass 中有 'public Guid ClassId { get; set; }'
|
||||
.OnDelete(DeleteBehavior.Cascade); // 常见:如果一个班级被删除,其作业关联也应被删除。
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
using Entities.Contracts;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace TechHelper.Context.Configuration
|
||||
{
|
||||
public class ClassStudentConfiguration : IEntityTypeConfiguration<ClassStudent>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<ClassStudent> builder)
|
||||
{
|
||||
// 1. 设置表名
|
||||
// 将此实体映射到数据库中名为 "class_student" 的表。
|
||||
builder.ToTable("class_student");
|
||||
|
||||
// 2. 设置复合主键
|
||||
// ClassId 和 StudentId 的组合作为主键,确保一个班级中一个学生只有一条入学记录。
|
||||
builder.HasKey(cs => new { cs.ClassId, cs.StudentId });
|
||||
|
||||
// 3. 配置列名和属性特性
|
||||
|
||||
// 配置 ClassId 属性对应的数据库列名为 "class_id"。
|
||||
builder.Property(cs => cs.ClassId)
|
||||
.HasColumnName("class_id");
|
||||
|
||||
// 配置 StudentId 属性对应的数据库列名为 "student_id"。
|
||||
builder.Property(cs => cs.StudentId)
|
||||
.HasColumnName("student_id");
|
||||
|
||||
// 配置 EnrollmentDate 属性对应的数据库列名为 "enrollment_date",并设置为必需字段。
|
||||
builder.Property(cs => cs.EnrollmentDate)
|
||||
.HasColumnName("enrollment_date")
|
||||
.IsRequired();
|
||||
|
||||
// 配置 IsDeleted 属性对应的数据库列名为 "deleted",并设置默认值为 false。
|
||||
builder.Property(cs => cs.IsDeleted)
|
||||
.HasColumnName("deleted")
|
||||
.HasDefaultValue(false); // 常用作软删除标记
|
||||
|
||||
// 4. 配置导航属性和外键关系
|
||||
|
||||
// ---
|
||||
// 配置 ClassStudent 到 Class 的关系 (多对一)
|
||||
// 一个 ClassStudent 联结记录属于一个 Class。
|
||||
//
|
||||
// 假设 `Class` 实体中有一个名为 `ClassStudents` 的 `ICollection<ClassStudent>` 集合属性。
|
||||
builder.HasOne(cs => cs.Class) // 当前 ClassStudent 链接到一个 Class
|
||||
.WithMany(c => c.ClassStudents) // 那个 Class 可以有多个 ClassStudent 记录
|
||||
.HasForeignKey(cs => cs.ClassId) // 外键是 ClassStudent.ClassId
|
||||
.OnDelete(DeleteBehavior.Cascade); // 当 Class 被删除时,相关的 ClassStudent 记录也级联删除。
|
||||
|
||||
// ---
|
||||
// 配置 ClassStudent 到 User (Student) 的关系 (多对一)
|
||||
// 一个 ClassStudent 联结记录属于一个 User (作为 Student)。
|
||||
//
|
||||
// 假设 `User` 实体中有一个名为 `EnrolledClassesLink` 的 `ICollection<ClassStudent>` 集合属性,
|
||||
// 用于表示该用户所注册的班级联结记录 (与 `ClassTeacherConfiguration` 中的模式类似)。
|
||||
builder.HasOne(cs => cs.Student) // 当前 ClassStudent 链接到一个 User (学生)
|
||||
.WithMany(u => u.EnrolledClassesLink) // 那个 User (学生) 可以有多个 ClassStudent 记录
|
||||
.HasForeignKey(cs => cs.StudentId) // 外键是 ClassStudent.StudentId
|
||||
.OnDelete(DeleteBehavior.Restrict); // 当 User (学生) 被删除时,如果还有相关的 ClassStudent 记录,则会阻止删除。
|
||||
// 这是更安全的做法,以避免意外数据丢失。如果你希望学生被删除时,其所有注册关系也一并删除,可改为 DeleteBehavior.Cascade。
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
using Entities.Contracts;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace TechHelper.Context.Configuration
|
||||
{
|
||||
public class ClassTeacherConfiguration : IEntityTypeConfiguration<ClassTeacher>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<ClassTeacher> builder)
|
||||
{
|
||||
// 1. 设置表名
|
||||
// 将此实体映射到数据库中名为 "class_teachers" 的表。
|
||||
builder.ToTable("class_teachers");
|
||||
|
||||
// 2. 设置复合主键
|
||||
// ClassId 和 TeacherId 的组合作为主键,确保一个班级中一个老师只有一条任教记录。
|
||||
// 这要求 ClassTeacher 类中的 ClassId 和 TeacherId 属性上都添加了 [Key] 特性。
|
||||
builder.HasKey(ct => new { ct.ClassId, ct.TeacherId });
|
||||
|
||||
// 3. 配置列名和属性特性
|
||||
|
||||
// 配置 ClassId 属性对应的数据库列名为 "class_id"。
|
||||
builder.Property(ct => ct.ClassId)
|
||||
.HasColumnName("class_id");
|
||||
|
||||
// 配置 TeacherId 属性对应的数据库列名为 "teacher_id"。
|
||||
builder.Property(ct => ct.TeacherId)
|
||||
.HasColumnName("teacher_id");
|
||||
|
||||
// 配置 SubjectTaught 属性对应的数据库列名为 "subject_taught"。
|
||||
// 假设 SubjectTaught 可以为空,所以没有 .IsRequired()
|
||||
builder.Property(ct => ct.SubjectTaught)
|
||||
.HasColumnName("subject_taught");
|
||||
|
||||
// 4. 配置导航属性和外键关系
|
||||
|
||||
// ---
|
||||
// 配置 ClassTeacher 到 Class 的关系 (多对一)
|
||||
// 一个 ClassTeacher 联结记录属于一个 Class。
|
||||
//
|
||||
// 假设 `Class` 实体中有一个名为 `ClassTeachers` 的 `ICollection<ClassTeacher>` 集合属性。
|
||||
builder.HasOne(ct => ct.Class) // 当前 ClassTeacher 链接到一个 Class
|
||||
.WithMany(c => c.ClassTeachers) // 那个 Class 可以有多个 ClassTeacher 记录
|
||||
.HasForeignKey(ct => ct.ClassId) // 外键是 ClassTeacher.ClassId
|
||||
.OnDelete(DeleteBehavior.Cascade); // 当 Class 被删除时,相关的 ClassTeacher 记录也级联删除。
|
||||
|
||||
// ---
|
||||
// 配置 ClassTeacher 到 User (Teacher) 的关系 (多对一)
|
||||
// 一个 ClassTeacher 联结记录属于一个 User (作为 Teacher)。
|
||||
//
|
||||
// 假设 `User` 实体中有一个名为 `TaughtClassesLink` 的 `ICollection<ClassTeacher>` 集合属性,
|
||||
// 用于表示该用户所教授的班级联结记录。
|
||||
builder.HasOne(ct => ct.Teacher) // 当前 ClassTeacher 链接到一个 User (老师)
|
||||
.WithMany(u => u.TaughtClassesLink) // 那个 User (老师) 可以有多个 ClassTeacher 记录 (为所教授的班级)
|
||||
.HasForeignKey(ct => ct.TeacherId) // 外键是 ClassTeacher.TeacherId
|
||||
.OnDelete(DeleteBehavior.Cascade); // 当 User (老师) 被删除时,如果还有相关的 ClassTeacher 记录,则会阻止删除。
|
||||
// 这通常是防止数据丢失的更安全选择。如果你希望老师被删除时,其所有任教关系也一并删除,可改为 DeleteBehavior.Cascade。
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -95,7 +95,7 @@ namespace TechHelper.Context.Configuration
|
||||
//
|
||||
// 这个关系的外键配置通常在 "多" 的一方(`AssignmentQuestion` 实体)进行。
|
||||
// 假设 `AssignmentQuestion` 实体有一个 `QuestionId` 外键和 `Question` 导航属性。
|
||||
builder.HasMany(q => q.AssignmentQuestions) // 当前 Question 有多个 AssignmentQuestion
|
||||
builder.HasMany(q => q.ExamQuestions) // 当前 Question 有多个 AssignmentQuestion
|
||||
.WithOne(aq => aq.Question); // 每一个 AssignmentQuestion 都有一个 Question
|
||||
// .HasForeignKey(aq => aq.QuestionId); // 外键的配置应在 `AssignmentQuestionConfiguration` 中进行
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace TechHelper.Context.Configuration
|
||||
.HasColumnName("id");
|
||||
|
||||
// AssignmentId
|
||||
builder.Property(s => s.AssignmentId)
|
||||
builder.Property(s => s.ExamId)
|
||||
.HasColumnName("assignment_id")
|
||||
.IsRequired();
|
||||
|
||||
@@ -67,9 +67,9 @@ namespace TechHelper.Context.Configuration
|
||||
|
||||
|
||||
|
||||
builder.HasOne(s => s.Assignment) // 当前 Submission 有一个 Assignment
|
||||
builder.HasOne(s => s.Exam) // 当前 Submission 有一个 Assignment
|
||||
.WithMany(a => a.Submissions) // 那个 Assignment 可以有多个 Submission
|
||||
.HasForeignKey(s => s.AssignmentId) // 外键是 Submission.AssignmentId
|
||||
.HasForeignKey(s => s.ExamId) // 外键是 Submission.AssignmentId
|
||||
.OnDelete(DeleteBehavior.Cascade); // 当 Assignment 被删除时,相关的 Submission 也级联删除。
|
||||
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace TechHelper.Context.Configuration
|
||||
.HasColumnName("student_id")
|
||||
.IsRequired();
|
||||
|
||||
builder.Property(sd => sd.AssignmentQuestionId)
|
||||
builder.Property(sd => sd.ExamQuestionId)
|
||||
.HasColumnName("assignment_question_id")
|
||||
.IsRequired();
|
||||
|
||||
@@ -67,9 +67,9 @@ namespace TechHelper.Context.Configuration
|
||||
.OnDelete(DeleteBehavior.Cascade); // 当 User (学生) 被删除时,如果他/她还有提交详情,则会阻止删除。
|
||||
// 这是一个更安全的选择,以防止意外数据丢失。
|
||||
|
||||
builder.HasOne(sd => sd.AssignmentQuestion) // 当前 SubmissionDetail 有一个 AssignmentQuestion
|
||||
builder.HasOne(sd => sd.ExamQuestion) // 当前 SubmissionDetail 有一个 AssignmentQuestion
|
||||
.WithMany(aq => aq.SubmissionDetails) // 那个 AssignmentQuestion 可以有多个 SubmissionDetail 记录
|
||||
.HasForeignKey(sd => sd.AssignmentQuestionId) // 外键是 SubmissionDetail.AssignmentQuestionId
|
||||
.HasForeignKey(sd => sd.ExamQuestionId) // 外键是 SubmissionDetail.AssignmentQuestionId
|
||||
.OnDelete(DeleteBehavior.Cascade); // 当 AssignmentQuestion 被删除时,相关的 SubmissionDetail 记录也级联删除。
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace TechHelper.Context.Configuration
|
||||
.OnDelete(DeleteBehavior.Restrict); // 限制删除:如果创建者有题目,则不允许删除
|
||||
|
||||
// User 作为创建者,与 Assignment 的关系 (一对多)
|
||||
builder.HasMany(u => u.CreatedAssignments) // 一个 User 可以创建多个作业
|
||||
builder.HasMany(u => u.CreatedExams) // 一个 User 可以创建多个作业
|
||||
.WithOne(a => a.Creator) // 一个 Assignment 对应一个 Creator
|
||||
.HasForeignKey(a => a.CreatorId) // 外键在 Assignment.CreatedBy
|
||||
.OnDelete(DeleteBehavior.Restrict); // 限制删除:如果创建者有作业,则不允许删除
|
||||
|
||||
22
TechHelper.Server/Context/DbInitializer.cs
Normal file
22
TechHelper.Server/Context/DbInitializer.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using Entities.Contracts;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
|
||||
namespace TechHelper.Server.Context
|
||||
{
|
||||
public class DbInitializer
|
||||
{
|
||||
public static async Task SeedRoles(RoleManager<IdentityRole<Guid>> roleManager)
|
||||
{
|
||||
string[] defaultRoleName = { "Admin", "Teacher", "Student" };
|
||||
|
||||
foreach (var roleName in defaultRoleName)
|
||||
{
|
||||
if (!await roleManager.RoleExistsAsync(roleName))
|
||||
{
|
||||
await roleManager.CreateAsync(new IdentityRole<Guid>(roleName));
|
||||
Console.WriteLine($"Default role '{roleName}' created successfully.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user