自动排课:保留手工安排,按教师、行政班、周次、节次、容量和场地约束补排。

课程约束:可限定校区、教学楼、指定教室、允许上课日、最早/最晚节次。
无教室课程:教室可为空,但仍校验教师和班级冲突。
作息维护:按学期维护节次、上下课时间和启用状态。
发布保护:发布前重新检查全部约束,并阻止学时未排满的课表发布。
工作台升级:增加“排课规则与作息”“自动排课”入口,自动生成后仍支持手工微调。
同时兼容 SQLite 和 MySQL,已生成正式迁移。
This commit is contained in:
2026-07-24 19:19:18 +08:00 Unverified
parent d7cf3f9e76
commit 6538b6080a
19 changed files with 4344 additions and 37 deletions
@@ -29,6 +29,11 @@ public sealed class AppDbContext(DbContextOptions<AppDbContext> options)
public DbSet<TeachingTaskClass> TeachingTaskClasses => Set<TeachingTaskClass>();
public DbSet<SchedulePlan> SchedulePlans => Set<SchedulePlan>();
public DbSet<ScheduleEntry> ScheduleEntries => Set<ScheduleEntry>();
public DbSet<ScheduleTimeSlot> ScheduleTimeSlots => Set<ScheduleTimeSlot>();
public DbSet<TeachingTaskScheduleConstraint> TeachingTaskScheduleConstraints =>
Set<TeachingTaskScheduleConstraint>();
public DbSet<TeachingTaskAllowedClassroom> TeachingTaskAllowedClassrooms =>
Set<TeachingTaskAllowedClassroom>();
public DbSet<CourseSelectionRound> CourseSelectionRounds =>
Set<CourseSelectionRound>();
public DbSet<CourseSelectionOffering> CourseSelectionOfferings =>
@@ -293,6 +298,51 @@ public sealed class AppDbContext(DbContextOptions<AppDbContext> options)
.WithMany()
.HasForeignKey(x => x.TeachingTaskId)
.OnDelete(DeleteBehavior.Restrict);
entity.HasOne(x => x.Classroom)
.WithMany()
.HasForeignKey(x => x.ClassroomId)
.OnDelete(DeleteBehavior.SetNull);
});
builder.Entity<ScheduleTimeSlot>(entity =>
{
entity.Property(x => x.Name).HasMaxLength(40);
entity.HasIndex(x => new { x.AcademicTermId, x.PeriodNumber }).IsUnique();
entity.HasOne(x => x.AcademicTerm)
.WithMany()
.HasForeignKey(x => x.AcademicTermId)
.OnDelete(DeleteBehavior.Cascade);
});
builder.Entity<TeachingTaskScheduleConstraint>(entity =>
{
entity.Property(x => x.AllowedDayOfWeeks).HasMaxLength(20);
entity.HasIndex(x => x.TeachingTaskId).IsUnique();
entity.HasOne(x => x.TeachingTask)
.WithMany()
.HasForeignKey(x => x.TeachingTaskId)
.OnDelete(DeleteBehavior.Cascade);
entity.HasOne(x => x.RequiredCampus)
.WithMany()
.HasForeignKey(x => x.RequiredCampusId)
.OnDelete(DeleteBehavior.Restrict);
entity.HasOne(x => x.RequiredBuilding)
.WithMany()
.HasForeignKey(x => x.RequiredBuildingId)
.OnDelete(DeleteBehavior.Restrict);
});
builder.Entity<TeachingTaskAllowedClassroom>(entity =>
{
entity.HasKey(x => new
{
x.TeachingTaskScheduleConstraintId,
x.ClassroomId
});
entity.HasOne(x => x.TeachingTaskScheduleConstraint)
.WithMany(x => x.AllowedClassrooms)
.HasForeignKey(x => x.TeachingTaskScheduleConstraintId)
.OnDelete(DeleteBehavior.Cascade);
entity.HasOne(x => x.Classroom)
.WithMany()
.HasForeignKey(x => x.ClassroomId)
@@ -19,6 +19,8 @@ public sealed class DevelopmentSqliteMigrator(
private const string DegreeAwardsMigration = "20260724_11_degree_awards";
private const string GraduationClearanceMigration = "20260724_12_graduation_clearance";
private const string CourseCategoriesMigration = "20260724_13_course_categories";
private const string SchedulingOptimizationMigration =
"20260724_14_scheduling_optimization";
public async Task MigrateAsync(CancellationToken cancellationToken = default)
{
@@ -107,6 +109,18 @@ public sealed class DevelopmentSqliteMigrator(
"ALTER TABLE", StringComparison.OrdinalIgnoreCase))
: CourseCategoriesStatements,
cancellationToken);
var schedulingOptimizationExists = await db.Database
.SqlQueryRaw<int>(
"""
SELECT COUNT(*) AS "Value"
FROM sqlite_master
WHERE type = 'table' AND name = 'ScheduleTimeSlots'
""")
.AnyAsync(value => value > 0, cancellationToken);
await ApplyMigrationAsync(
SchedulingOptimizationMigration,
schedulingOptimizationExists ? [] : SchedulingOptimizationStatements,
cancellationToken);
}
private async Task ApplyMigrationAsync(
@@ -814,4 +828,129 @@ public sealed class DevelopmentSqliteMigrator(
ON "Courses" ("CourseCategoryId");
"""
];
private static readonly string[] SchedulingOptimizationStatements =
[
"""
CREATE TABLE "ScheduleEntries_New" (
"Id" TEXT NOT NULL CONSTRAINT "PK_ScheduleEntries" PRIMARY KEY,
"SchedulePlanId" TEXT NOT NULL,
"TeachingTaskId" TEXT NOT NULL,
"ClassroomId" TEXT NULL,
"DayOfWeek" INTEGER NOT NULL,
"StartPeriod" INTEGER NOT NULL,
"PeriodCount" INTEGER NOT NULL,
"StartWeek" INTEGER NOT NULL,
"EndWeek" INTEGER NOT NULL,
"WeekPattern" INTEGER NOT NULL,
"Notes" TEXT NULL,
"CreatedAt" TEXT NOT NULL,
"UpdatedAt" TEXT NOT NULL,
CONSTRAINT "FK_ScheduleEntries_SchedulePlans_SchedulePlanId"
FOREIGN KEY ("SchedulePlanId") REFERENCES "SchedulePlans" ("Id")
ON DELETE CASCADE,
CONSTRAINT "FK_ScheduleEntries_TeachingTasks_TeachingTaskId"
FOREIGN KEY ("TeachingTaskId") REFERENCES "TeachingTasks" ("Id")
ON DELETE RESTRICT,
CONSTRAINT "FK_ScheduleEntries_Classrooms_ClassroomId"
FOREIGN KEY ("ClassroomId") REFERENCES "Classrooms" ("Id")
ON DELETE SET NULL
);
""",
"""
INSERT INTO "ScheduleEntries_New"
SELECT "Id", "SchedulePlanId", "TeachingTaskId", "ClassroomId",
"DayOfWeek", "StartPeriod", "PeriodCount", "StartWeek", "EndWeek",
"WeekPattern", "Notes", "CreatedAt", "UpdatedAt"
FROM "ScheduleEntries";
""",
"""DROP TABLE "ScheduleEntries";""",
"""ALTER TABLE "ScheduleEntries_New" RENAME TO "ScheduleEntries";""",
"""
CREATE INDEX "IX_ScheduleEntries_SchedulePlanId_DayOfWeek_StartPeriod"
ON "ScheduleEntries" ("SchedulePlanId", "DayOfWeek", "StartPeriod");
""",
"""
CREATE INDEX "IX_ScheduleEntries_TeachingTaskId"
ON "ScheduleEntries" ("TeachingTaskId");
""",
"""
CREATE INDEX "IX_ScheduleEntries_ClassroomId"
ON "ScheduleEntries" ("ClassroomId");
""",
"""
CREATE TABLE "ScheduleTimeSlots" (
"Id" TEXT NOT NULL CONSTRAINT "PK_ScheduleTimeSlots" PRIMARY KEY,
"AcademicTermId" TEXT NOT NULL,
"PeriodNumber" INTEGER NOT NULL,
"Name" TEXT NOT NULL,
"StartsAt" TEXT NOT NULL,
"EndsAt" TEXT NOT NULL,
"IsEnabled" INTEGER NOT NULL,
"CreatedAt" TEXT NOT NULL,
"UpdatedAt" TEXT NOT NULL,
CONSTRAINT "FK_ScheduleTimeSlots_AcademicTerms_AcademicTermId"
FOREIGN KEY ("AcademicTermId") REFERENCES "AcademicTerms" ("Id")
ON DELETE CASCADE
);
""",
"""
CREATE UNIQUE INDEX "IX_ScheduleTimeSlots_AcademicTermId_PeriodNumber"
ON "ScheduleTimeSlots" ("AcademicTermId", "PeriodNumber");
""",
"""
CREATE TABLE "TeachingTaskScheduleConstraints" (
"Id" TEXT NOT NULL CONSTRAINT "PK_TeachingTaskScheduleConstraints" PRIMARY KEY,
"TeachingTaskId" TEXT NOT NULL,
"RequiresClassroom" INTEGER NOT NULL,
"RequiredCampusId" TEXT NULL,
"RequiredBuildingId" TEXT NULL,
"AllowedDayOfWeeks" TEXT NULL,
"EarliestPeriod" INTEGER NULL,
"LatestPeriod" INTEGER NULL,
"CreatedAt" TEXT NOT NULL,
"UpdatedAt" TEXT NOT NULL,
CONSTRAINT "FK_TeachingTaskScheduleConstraints_TeachingTasks_TeachingTaskId"
FOREIGN KEY ("TeachingTaskId") REFERENCES "TeachingTasks" ("Id")
ON DELETE CASCADE,
CONSTRAINT "FK_TeachingTaskScheduleConstraints_Campuses_RequiredCampusId"
FOREIGN KEY ("RequiredCampusId") REFERENCES "Campuses" ("Id")
ON DELETE RESTRICT,
CONSTRAINT "FK_TeachingTaskScheduleConstraints_Buildings_RequiredBuildingId"
FOREIGN KEY ("RequiredBuildingId") REFERENCES "Buildings" ("Id")
ON DELETE RESTRICT
);
""",
"""
CREATE UNIQUE INDEX "IX_TeachingTaskScheduleConstraints_TeachingTaskId"
ON "TeachingTaskScheduleConstraints" ("TeachingTaskId");
""",
"""
CREATE INDEX "IX_TeachingTaskScheduleConstraints_RequiredCampusId"
ON "TeachingTaskScheduleConstraints" ("RequiredCampusId");
""",
"""
CREATE INDEX "IX_TeachingTaskScheduleConstraints_RequiredBuildingId"
ON "TeachingTaskScheduleConstraints" ("RequiredBuildingId");
""",
"""
CREATE TABLE "TeachingTaskAllowedClassrooms" (
"TeachingTaskScheduleConstraintId" TEXT NOT NULL,
"ClassroomId" TEXT NOT NULL,
CONSTRAINT "PK_TeachingTaskAllowedClassrooms"
PRIMARY KEY ("TeachingTaskScheduleConstraintId", "ClassroomId"),
CONSTRAINT "FK_TeachingTaskAllowedClassrooms_Constraints"
FOREIGN KEY ("TeachingTaskScheduleConstraintId")
REFERENCES "TeachingTaskScheduleConstraints" ("Id")
ON DELETE CASCADE,
CONSTRAINT "FK_TeachingTaskAllowedClassrooms_Classrooms_ClassroomId"
FOREIGN KEY ("ClassroomId") REFERENCES "Classrooms" ("Id")
ON DELETE RESTRICT
);
""",
"""
CREATE INDEX "IX_TeachingTaskAllowedClassrooms_ClassroomId"
ON "TeachingTaskAllowedClassrooms" ("ClassroomId");
"""
];
}
@@ -0,0 +1,187 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
{
/// <inheritdoc />
public partial class SchedulingOptimization : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_ScheduleEntries_Classrooms_ClassroomId",
table: "ScheduleEntries");
migrationBuilder.AlterColumn<Guid>(
name: "ClassroomId",
table: "ScheduleEntries",
type: "char(36)",
nullable: true,
oldClrType: typeof(Guid),
oldType: "char(36)");
migrationBuilder.CreateTable(
name: "ScheduleTimeSlots",
columns: table => new
{
Id = table.Column<Guid>(type: "char(36)", nullable: false),
AcademicTermId = table.Column<Guid>(type: "char(36)", nullable: false),
PeriodNumber = table.Column<int>(type: "int", nullable: false),
Name = table.Column<string>(type: "varchar(40)", maxLength: 40, nullable: false),
StartsAt = table.Column<TimeOnly>(type: "time", nullable: false),
EndsAt = table.Column<TimeOnly>(type: "time", nullable: false),
IsEnabled = table.Column<bool>(type: "tinyint(1)", nullable: false),
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
UpdatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ScheduleTimeSlots", x => x.Id);
table.ForeignKey(
name: "FK_ScheduleTimeSlots_AcademicTerms_AcademicTermId",
column: x => x.AcademicTermId,
principalTable: "AcademicTerms",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySQL:Charset", "utf8mb4");
migrationBuilder.CreateTable(
name: "TeachingTaskScheduleConstraints",
columns: table => new
{
Id = table.Column<Guid>(type: "char(36)", nullable: false),
TeachingTaskId = table.Column<Guid>(type: "char(36)", nullable: false),
RequiresClassroom = table.Column<bool>(type: "tinyint(1)", nullable: false),
RequiredCampusId = table.Column<Guid>(type: "char(36)", nullable: true),
RequiredBuildingId = table.Column<Guid>(type: "char(36)", nullable: true),
AllowedDayOfWeeks = table.Column<string>(type: "varchar(20)", maxLength: 20, nullable: true),
EarliestPeriod = table.Column<int>(type: "int", nullable: true),
LatestPeriod = table.Column<int>(type: "int", nullable: true),
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
UpdatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_TeachingTaskScheduleConstraints", x => x.Id);
table.ForeignKey(
name: "FK_TeachingTaskScheduleConstraints_Buildings_RequiredBuildingId",
column: x => x.RequiredBuildingId,
principalTable: "Buildings",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_TeachingTaskScheduleConstraints_Campuses_RequiredCampusId",
column: x => x.RequiredCampusId,
principalTable: "Campuses",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_TeachingTaskScheduleConstraints_TeachingTasks_TeachingTaskId",
column: x => x.TeachingTaskId,
principalTable: "TeachingTasks",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySQL:Charset", "utf8mb4");
migrationBuilder.CreateTable(
name: "TeachingTaskAllowedClassrooms",
columns: table => new
{
TeachingTaskScheduleConstraintId = table.Column<Guid>(type: "char(36)", nullable: false),
ClassroomId = table.Column<Guid>(type: "char(36)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_TeachingTaskAllowedClassrooms", x => new { x.TeachingTaskScheduleConstraintId, x.ClassroomId });
table.ForeignKey(
name: "FK_TeachingTaskAllowedClassrooms_Classrooms_ClassroomId",
column: x => x.ClassroomId,
principalTable: "Classrooms",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_TeachingTaskAllowedClassrooms_TeachingTaskScheduleConstraint~",
column: x => x.TeachingTaskScheduleConstraintId,
principalTable: "TeachingTaskScheduleConstraints",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySQL:Charset", "utf8mb4");
migrationBuilder.CreateIndex(
name: "IX_ScheduleTimeSlots_AcademicTermId_PeriodNumber",
table: "ScheduleTimeSlots",
columns: new[] { "AcademicTermId", "PeriodNumber" },
unique: true);
migrationBuilder.CreateIndex(
name: "IX_TeachingTaskAllowedClassrooms_ClassroomId",
table: "TeachingTaskAllowedClassrooms",
column: "ClassroomId");
migrationBuilder.CreateIndex(
name: "IX_TeachingTaskScheduleConstraints_RequiredBuildingId",
table: "TeachingTaskScheduleConstraints",
column: "RequiredBuildingId");
migrationBuilder.CreateIndex(
name: "IX_TeachingTaskScheduleConstraints_RequiredCampusId",
table: "TeachingTaskScheduleConstraints",
column: "RequiredCampusId");
migrationBuilder.CreateIndex(
name: "IX_TeachingTaskScheduleConstraints_TeachingTaskId",
table: "TeachingTaskScheduleConstraints",
column: "TeachingTaskId",
unique: true);
migrationBuilder.AddForeignKey(
name: "FK_ScheduleEntries_Classrooms_ClassroomId",
table: "ScheduleEntries",
column: "ClassroomId",
principalTable: "Classrooms",
principalColumn: "Id",
onDelete: ReferentialAction.SetNull);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_ScheduleEntries_Classrooms_ClassroomId",
table: "ScheduleEntries");
migrationBuilder.DropTable(
name: "ScheduleTimeSlots");
migrationBuilder.DropTable(
name: "TeachingTaskAllowedClassrooms");
migrationBuilder.DropTable(
name: "TeachingTaskScheduleConstraints");
migrationBuilder.AlterColumn<Guid>(
name: "ClassroomId",
table: "ScheduleEntries",
type: "char(36)",
nullable: false,
defaultValue: new Guid("00000000-0000-0000-0000-000000000000"),
oldClrType: typeof(Guid),
oldType: "char(36)",
oldNullable: true);
migrationBuilder.AddForeignKey(
name: "FK_ScheduleEntries_Classrooms_ClassroomId",
table: "ScheduleEntries",
column: "ClassroomId",
principalTable: "Classrooms",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
}
}
}
@@ -1292,7 +1292,7 @@ namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<Guid>("ClassroomId")
b.Property<Guid?>("ClassroomId")
.HasColumnType("char(36)");
b.Property<DateTime>("CreatedAt")
@@ -1385,6 +1385,46 @@ namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
b.ToTable("SchedulePlans");
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.ScheduleTimeSlot", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<Guid>("AcademicTermId")
.HasColumnType("char(36)");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<TimeOnly>("EndsAt")
.HasColumnType("time");
b.Property<bool>("IsEnabled")
.HasColumnType("tinyint(1)");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(40)
.HasColumnType("varchar(40)");
b.Property<int>("PeriodNumber")
.HasColumnType("int");
b.Property<TimeOnly>("StartsAt")
.HasColumnType("time");
b.Property<DateTime>("UpdatedAt")
.HasColumnType("datetime(6)");
b.HasKey("Id");
b.HasIndex("AcademicTermId", "PeriodNumber")
.IsUnique();
b.ToTable("ScheduleTimeSlots");
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.Student", b =>
{
b.Property<Guid>("Id")
@@ -1636,6 +1676,21 @@ namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
b.ToTable("TeachingTasks");
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.TeachingTaskAllowedClassroom", b =>
{
b.Property<Guid>("TeachingTaskScheduleConstraintId")
.HasColumnType("char(36)");
b.Property<Guid>("ClassroomId")
.HasColumnType("char(36)");
b.HasKey("TeachingTaskScheduleConstraintId", "ClassroomId");
b.HasIndex("ClassroomId");
b.ToTable("TeachingTaskAllowedClassrooms");
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.TeachingTaskClass", b =>
{
b.Property<Guid>("TeachingTaskId")
@@ -1651,6 +1706,52 @@ namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
b.ToTable("TeachingTaskClasses");
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.TeachingTaskScheduleConstraint", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("AllowedDayOfWeeks")
.HasMaxLength(20)
.HasColumnType("varchar(20)");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<int?>("EarliestPeriod")
.HasColumnType("int");
b.Property<int?>("LatestPeriod")
.HasColumnType("int");
b.Property<Guid?>("RequiredBuildingId")
.HasColumnType("char(36)");
b.Property<Guid?>("RequiredCampusId")
.HasColumnType("char(36)");
b.Property<bool>("RequiresClassroom")
.HasColumnType("tinyint(1)");
b.Property<Guid>("TeachingTaskId")
.HasColumnType("char(36)");
b.Property<DateTime>("UpdatedAt")
.HasColumnType("datetime(6)");
b.HasKey("Id");
b.HasIndex("RequiredBuildingId");
b.HasIndex("RequiredCampusId");
b.HasIndex("TeachingTaskId")
.IsUnique();
b.ToTable("TeachingTaskScheduleConstraints");
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.TeachingTaskTeacher", b =>
{
b.Property<Guid>("TeachingTaskId")
@@ -2277,8 +2378,7 @@ namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
b.HasOne("Jiaowu.Api.Domain.Academic.Classroom", "Classroom")
.WithMany()
.HasForeignKey("ClassroomId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
.OnDelete(DeleteBehavior.SetNull);
b.HasOne("Jiaowu.Api.Domain.Academic.SchedulePlan", "SchedulePlan")
.WithMany("Entries")
@@ -2310,6 +2410,17 @@ namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
b.Navigation("AcademicTerm");
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.ScheduleTimeSlot", b =>
{
b.HasOne("Jiaowu.Api.Domain.Academic.AcademicTerm", "AcademicTerm")
.WithMany()
.HasForeignKey("AcademicTermId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("AcademicTerm");
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.Student", b =>
{
b.HasOne("Jiaowu.Api.Domain.Academic.AdministrativeClass", "AdministrativeClass")
@@ -2372,6 +2483,25 @@ namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
b.Navigation("Course");
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.TeachingTaskAllowedClassroom", b =>
{
b.HasOne("Jiaowu.Api.Domain.Academic.Classroom", "Classroom")
.WithMany()
.HasForeignKey("ClassroomId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("Jiaowu.Api.Domain.Academic.TeachingTaskScheduleConstraint", "TeachingTaskScheduleConstraint")
.WithMany("AllowedClassrooms")
.HasForeignKey("TeachingTaskScheduleConstraintId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Classroom");
b.Navigation("TeachingTaskScheduleConstraint");
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.TeachingTaskClass", b =>
{
b.HasOne("Jiaowu.Api.Domain.Academic.AdministrativeClass", "AdministrativeClass")
@@ -2391,6 +2521,31 @@ namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
b.Navigation("TeachingTask");
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.TeachingTaskScheduleConstraint", b =>
{
b.HasOne("Jiaowu.Api.Domain.Academic.Building", "RequiredBuilding")
.WithMany()
.HasForeignKey("RequiredBuildingId")
.OnDelete(DeleteBehavior.Restrict);
b.HasOne("Jiaowu.Api.Domain.Academic.Campus", "RequiredCampus")
.WithMany()
.HasForeignKey("RequiredCampusId")
.OnDelete(DeleteBehavior.Restrict);
b.HasOne("Jiaowu.Api.Domain.Academic.TeachingTask", "TeachingTask")
.WithMany()
.HasForeignKey("TeachingTaskId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("RequiredBuilding");
b.Navigation("RequiredCampus");
b.Navigation("TeachingTask");
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.TeachingTaskTeacher", b =>
{
b.HasOne("Jiaowu.Api.Domain.Academic.Teacher", "Teacher")
@@ -2532,6 +2687,11 @@ namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
b.Navigation("Teachers");
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.TeachingTaskScheduleConstraint", b =>
{
b.Navigation("AllowedClassrooms");
});
#pragma warning restore 612, 618
}
}