This commit is contained in:
2026-07-24 13:11:09 +08:00 Unverified
parent 6c3021ea8d
commit 30d793773c
23 changed files with 3479 additions and 79 deletions
@@ -17,6 +17,9 @@ public sealed class AppDbContext(DbContextOptions<AppDbContext> options)
public DbSet<Building> Buildings => Set<Building>();
public DbSet<Classroom> Classrooms => Set<Classroom>();
public DbSet<AcademicTerm> AcademicTerms => Set<AcademicTerm>();
public DbSet<Teacher> Teachers => Set<Teacher>();
public DbSet<Student> Students => Set<Student>();
public DbSet<Course> Courses => Set<Course>();
public DbSet<AuditLog> AuditLogs => Set<AuditLog>();
protected override void OnModelCreating(ModelBuilder builder)
@@ -42,6 +45,7 @@ public sealed class AppDbContext(DbContextOptions<AppDbContext> options)
ConfigureCatalog<Building>(builder);
ConfigureCatalog<Classroom>(builder);
ConfigureCatalog<AcademicTerm>(builder);
ConfigureCatalog<Course>(builder);
builder.Entity<College>()
.HasOne(x => x.Campus)
@@ -76,6 +80,58 @@ public sealed class AppDbContext(DbContextOptions<AppDbContext> options)
builder.Entity<AcademicTerm>()
.HasIndex(x => x.IsCurrent);
builder.Entity<Teacher>(entity =>
{
entity.Property(x => x.TeacherNumber).HasMaxLength(30);
entity.Property(x => x.Name).HasMaxLength(50);
entity.Property(x => x.Title).HasMaxLength(30);
entity.Property(x => x.Phone).HasMaxLength(30);
entity.Property(x => x.Email).HasMaxLength(100);
entity.Property(x => x.Notes).HasMaxLength(500);
entity.HasIndex(x => x.TeacherNumber).IsUnique();
entity.HasIndex(x => new { x.CollegeId, x.Status });
entity.HasOne(x => x.College)
.WithMany()
.HasForeignKey(x => x.CollegeId)
.OnDelete(DeleteBehavior.Restrict);
entity.HasOne<ApplicationUser>()
.WithMany()
.HasForeignKey(x => x.UserId)
.OnDelete(DeleteBehavior.SetNull);
});
builder.Entity<Student>(entity =>
{
entity.Property(x => x.StudentNumber).HasMaxLength(30);
entity.Property(x => x.Name).HasMaxLength(50);
entity.Property(x => x.Phone).HasMaxLength(30);
entity.Property(x => x.Email).HasMaxLength(100);
entity.Property(x => x.Notes).HasMaxLength(500);
entity.HasIndex(x => x.StudentNumber).IsUnique();
entity.HasIndex(x => new { x.AdministrativeClassId, x.Status });
entity.HasIndex(x => x.EnrollmentYear);
entity.HasOne(x => x.AdministrativeClass)
.WithMany()
.HasForeignKey(x => x.AdministrativeClassId)
.OnDelete(DeleteBehavior.Restrict);
entity.HasOne<ApplicationUser>()
.WithMany()
.HasForeignKey(x => x.UserId)
.OnDelete(DeleteBehavior.SetNull);
});
builder.Entity<Course>(entity =>
{
entity.Property(x => x.EnglishName).HasMaxLength(150);
entity.Property(x => x.Credits).HasPrecision(5, 2);
entity.Property(x => x.Description).HasMaxLength(1000);
entity.HasIndex(x => new { x.CollegeId, x.Nature });
entity.HasOne(x => x.College)
.WithMany()
.HasForeignKey(x => x.CollegeId)
.OnDelete(DeleteBehavior.Restrict);
});
builder.Entity<AuditLog>(entity =>
{
entity.Property(x => x.Method).HasMaxLength(10);
@@ -9,6 +9,7 @@ public sealed class DatabaseInitializer(
AppDbContext db,
RoleManager<ApplicationRole> roleManager,
UserManager<ApplicationUser> userManager,
DevelopmentSqliteMigrator sqliteMigrator,
IConfiguration configuration,
IHostEnvironment environment,
ILogger<DatabaseInitializer> logger)
@@ -18,6 +19,7 @@ public sealed class DatabaseInitializer(
if (environment.IsDevelopment())
{
await db.Database.EnsureCreatedAsync();
await sqliteMigrator.MigrateAsync();
}
else
{
@@ -108,71 +110,182 @@ public sealed class DatabaseInitializer(
private async Task SeedDevelopmentDataAsync()
{
if (await db.Campuses.AnyAsync())
if (!await db.Campuses.AnyAsync())
{
return;
var campus = new Campus
{
Code = "MAIN",
Name = "主校区",
Address = "大学路 1 号"
};
var college = new College
{
Code = "CS",
Name = "计算机学院",
ShortName = "计算机学院",
CampusId = campus.Id
};
var major = new Major
{
Code = "080901",
Name = "计算机科学与技术",
CollegeId = college.Id,
DegreeType = "工学学士",
SchoolingYears = 4
};
var building = new Building
{
Code = "J1",
Name = "第一教学楼",
CampusId = campus.Id
};
db.AddRange(
campus,
college,
major,
new AdministrativeClass
{
Code = "CS2026-01",
Name = "计科 2026-1 班",
MajorId = major.Id,
Grade = 2026,
CounselorName = "陈老师"
},
building,
new Classroom
{
Code = "J1-201",
Name = "J1-201",
BuildingId = building.Id,
Capacity = 60,
RoomType = "多媒体教室",
Equipment = "投影、扩声、录播"
},
new AcademicTerm
{
Code = "2026-2027-1",
Name = "2026—2027 学年第一学期",
AcademicYear = "2026-2027",
Season = TermSeason.Autumn,
StartDate = new DateOnly(2026, 9, 7),
EndDate = new DateOnly(2027, 1, 17),
IsCurrent = true
});
await db.SaveChangesAsync();
}
var campus = new Campus
{
Code = "MAIN",
Name = "主校区",
Address = "大学路 1 号"
};
var college = new College
{
Code = "CS",
Name = "计算机学院",
ShortName = "计算机学院",
CampusId = campus.Id
};
var major = new Major
{
Code = "080901",
Name = "计算机科学与技术",
CollegeId = college.Id,
DegreeType = "工学学士",
SchoolingYears = 4
};
var building = new Building
{
Code = "J1",
Name = "第一教学楼",
CampusId = campus.Id
};
var computerCollege = await db.Colleges.SingleAsync(x => x.Code == "CS");
var computerClass = await db.AdministrativeClasses
.SingleAsync(x => x.Code == "CS2026-01");
db.AddRange(
campus,
college,
major,
new AdministrativeClass
{
Code = "CS2026-01",
Name = "计科 2026-1 班",
MajorId = major.Id,
Grade = 2026,
CounselorName = "陈老师"
},
building,
new Classroom
{
Code = "J1-201",
Name = "J1-201",
BuildingId = building.Id,
Capacity = 60,
RoomType = "多媒体教室",
Equipment = "投影、扩声、录播"
},
new AcademicTerm
{
Code = "2026-2027-1",
Name = "2026—2027 学年第一学期",
AcademicYear = "2026-2027",
Season = TermSeason.Autumn,
StartDate = new DateOnly(2026, 9, 7),
EndDate = new DateOnly(2027, 1, 17),
IsCurrent = true
});
if (!await db.Teachers.AnyAsync())
{
db.Teachers.AddRange(
new Teacher
{
TeacherNumber = "T2026001",
Name = "陈明远",
Gender = Gender.Male,
CollegeId = computerCollege.Id,
Title = "副教授",
Status = TeacherStatus.Active,
HireDate = new DateOnly(2018, 7, 1),
Email = "chenmy@example.edu.cn"
},
new Teacher
{
TeacherNumber = "T2026002",
Name = "林书雅",
Gender = Gender.Female,
CollegeId = computerCollege.Id,
Title = "讲师",
Status = TeacherStatus.Active,
HireDate = new DateOnly(2022, 9, 1),
Email = "linsy@example.edu.cn"
});
}
if (!await db.Students.AnyAsync())
{
db.Students.AddRange(
new Student
{
StudentNumber = "202601001",
Name = "周启航",
Gender = Gender.Male,
AdministrativeClassId = computerClass.Id,
EnrollmentYear = 2026,
EnrollmentDate = new DateOnly(2026, 9, 7),
Status = StudentStatus.Active
},
new Student
{
StudentNumber = "202601002",
Name = "许知夏",
Gender = Gender.Female,
AdministrativeClassId = computerClass.Id,
EnrollmentYear = 2026,
EnrollmentDate = new DateOnly(2026, 9, 7),
Status = StudentStatus.Active
},
new Student
{
StudentNumber = "202601003",
Name = "方嘉树",
Gender = Gender.Male,
AdministrativeClassId = computerClass.Id,
EnrollmentYear = 2026,
EnrollmentDate = new DateOnly(2026, 9, 7),
Status = StudentStatus.Active
});
}
if (!await db.Courses.AnyAsync())
{
db.Courses.AddRange(
new Course
{
Code = "CS101",
Name = "程序设计基础",
EnglishName = "Fundamentals of Programming",
CollegeId = computerCollege.Id,
Credits = 4,
TotalHours = 64,
LectureHours = 40,
PracticeHours = 24,
Nature = CourseNature.MajorRequired,
AssessmentMethod = AssessmentMethod.Examination,
Description = "面向一年级学生的程序设计入门课程。"
},
new Course
{
Code = "CS201",
Name = "数据结构",
EnglishName = "Data Structures",
CollegeId = computerCollege.Id,
Credits = 3.5m,
TotalHours = 56,
LectureHours = 40,
PracticeHours = 16,
Nature = CourseNature.MajorRequired,
AssessmentMethod = AssessmentMethod.Examination
},
new Course
{
Code = "CS305",
Name = "软件工程实践",
EnglishName = "Software Engineering Practice",
CollegeId = computerCollege.Id,
Credits = 2,
TotalHours = 48,
LectureHours = 8,
PracticeHours = 40,
Nature = CourseNature.Practice,
AssessmentMethod = AssessmentMethod.Assessment
});
}
await db.SaveChangesAsync();
}
@@ -0,0 +1,169 @@
using Microsoft.EntityFrameworkCore;
namespace Jiaowu.Api.Infrastructure.Persistence;
public sealed class DevelopmentSqliteMigrator(
AppDbContext db,
ILogger<DevelopmentSqliteMigrator> logger)
{
private const string PeopleAndCoursesMigration = "20260724_01_people_courses";
public async Task MigrateAsync(CancellationToken cancellationToken = default)
{
if (!db.Database.IsSqlite())
{
return;
}
await db.Database.ExecuteSqlRawAsync(
"""
CREATE TABLE IF NOT EXISTS "__DevelopmentSchemaHistory" (
"MigrationId" TEXT NOT NULL CONSTRAINT "PK___DevelopmentSchemaHistory" PRIMARY KEY,
"AppliedAt" TEXT NOT NULL
);
""",
cancellationToken);
var applied = await db.Database
.SqlQuery<string>(
$"""
SELECT "MigrationId" AS "Value"
FROM "__DevelopmentSchemaHistory"
WHERE "MigrationId" = {PeopleAndCoursesMigration}
""")
.AnyAsync(cancellationToken);
if (applied)
{
return;
}
await using var transaction = await db.Database.BeginTransactionAsync(cancellationToken);
foreach (var statement in PeopleAndCoursesStatements)
{
await db.Database.ExecuteSqlRawAsync(statement, cancellationToken);
}
await db.Database.ExecuteSqlInterpolatedAsync(
$"""
INSERT INTO "__DevelopmentSchemaHistory" ("MigrationId", "AppliedAt")
VALUES ({PeopleAndCoursesMigration}, {DateTime.UtcNow});
""",
cancellationToken);
await transaction.CommitAsync(cancellationToken);
logger.LogInformation(
"Applied SQLite development schema migration {MigrationId}.",
PeopleAndCoursesMigration);
}
private static readonly string[] PeopleAndCoursesStatements =
[
"""
CREATE TABLE IF NOT EXISTS "Teachers" (
"Id" TEXT NOT NULL CONSTRAINT "PK_Teachers" PRIMARY KEY,
"TeacherNumber" TEXT NOT NULL,
"Name" TEXT NOT NULL,
"Gender" INTEGER NOT NULL,
"CollegeId" TEXT NOT NULL,
"Title" TEXT NULL,
"Status" INTEGER NOT NULL,
"HireDate" TEXT NULL,
"IsExternal" INTEGER NOT NULL,
"Phone" TEXT NULL,
"Email" TEXT NULL,
"Notes" TEXT NULL,
"UserId" TEXT NULL,
"CreatedAt" TEXT NOT NULL,
"UpdatedAt" TEXT NOT NULL,
CONSTRAINT "FK_Teachers_Colleges_CollegeId"
FOREIGN KEY ("CollegeId") REFERENCES "Colleges" ("Id") ON DELETE RESTRICT,
CONSTRAINT "FK_Teachers_AspNetUsers_UserId"
FOREIGN KEY ("UserId") REFERENCES "AspNetUsers" ("Id") ON DELETE SET NULL
);
""",
"""
CREATE UNIQUE INDEX IF NOT EXISTS "IX_Teachers_TeacherNumber"
ON "Teachers" ("TeacherNumber");
""",
"""
CREATE INDEX IF NOT EXISTS "IX_Teachers_CollegeId_Status"
ON "Teachers" ("CollegeId", "Status");
""",
"""
CREATE INDEX IF NOT EXISTS "IX_Teachers_UserId"
ON "Teachers" ("UserId");
""",
"""
CREATE TABLE IF NOT EXISTS "Students" (
"Id" TEXT NOT NULL CONSTRAINT "PK_Students" PRIMARY KEY,
"StudentNumber" TEXT NOT NULL,
"Name" TEXT NOT NULL,
"Gender" INTEGER NOT NULL,
"AdministrativeClassId" TEXT NOT NULL,
"EnrollmentYear" INTEGER NOT NULL,
"EnrollmentDate" TEXT NOT NULL,
"Status" INTEGER NOT NULL,
"DateOfBirth" TEXT NULL,
"Phone" TEXT NULL,
"Email" TEXT NULL,
"Notes" TEXT NULL,
"UserId" TEXT NULL,
"CreatedAt" TEXT NOT NULL,
"UpdatedAt" TEXT NOT NULL,
CONSTRAINT "FK_Students_AdministrativeClasses_AdministrativeClassId"
FOREIGN KEY ("AdministrativeClassId") REFERENCES "AdministrativeClasses" ("Id")
ON DELETE RESTRICT,
CONSTRAINT "FK_Students_AspNetUsers_UserId"
FOREIGN KEY ("UserId") REFERENCES "AspNetUsers" ("Id") ON DELETE SET NULL
);
""",
"""
CREATE UNIQUE INDEX IF NOT EXISTS "IX_Students_StudentNumber"
ON "Students" ("StudentNumber");
""",
"""
CREATE INDEX IF NOT EXISTS "IX_Students_AdministrativeClassId_Status"
ON "Students" ("AdministrativeClassId", "Status");
""",
"""
CREATE INDEX IF NOT EXISTS "IX_Students_EnrollmentYear"
ON "Students" ("EnrollmentYear");
""",
"""
CREATE INDEX IF NOT EXISTS "IX_Students_UserId"
ON "Students" ("UserId");
""",
"""
CREATE TABLE IF NOT EXISTS "Courses" (
"Id" TEXT NOT NULL CONSTRAINT "PK_Courses" PRIMARY KEY,
"CollegeId" TEXT NOT NULL,
"EnglishName" TEXT NULL,
"Credits" TEXT NOT NULL,
"TotalHours" INTEGER NOT NULL,
"LectureHours" INTEGER NOT NULL,
"PracticeHours" INTEGER NOT NULL,
"Nature" INTEGER NOT NULL,
"AssessmentMethod" INTEGER NOT NULL,
"Description" TEXT NULL,
"CreatedAt" TEXT NOT NULL,
"UpdatedAt" TEXT NOT NULL,
"Code" TEXT NOT NULL,
"Name" TEXT NOT NULL,
"SortOrder" INTEGER NOT NULL,
"IsEnabled" INTEGER NOT NULL,
CONSTRAINT "FK_Courses_Colleges_CollegeId"
FOREIGN KEY ("CollegeId") REFERENCES "Colleges" ("Id") ON DELETE RESTRICT
);
""",
"""
CREATE UNIQUE INDEX IF NOT EXISTS "IX_Courses_Code" ON "Courses" ("Code");
""",
"""
CREATE INDEX IF NOT EXISTS "IX_Courses_IsEnabled_SortOrder"
ON "Courses" ("IsEnabled", "SortOrder");
""",
"""
CREATE INDEX IF NOT EXISTS "IX_Courses_CollegeId_Nature"
ON "Courses" ("CollegeId", "Nature");
"""
];
}
@@ -0,0 +1,984 @@
// <auto-generated />
using System;
using Jiaowu.Api.Infrastructure.Persistence;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
{
[DbContext(typeof(AppDbContext))]
[Migration("20260724045307_PeopleAndCourses")]
partial class PeopleAndCourses
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "10.0.10")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.AcademicTerm", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("AcademicYear")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("Code")
.IsRequired()
.HasMaxLength(40)
.HasColumnType("varchar(40)");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<DateOnly>("EndDate")
.HasColumnType("date");
b.Property<bool>("IsCurrent")
.HasColumnType("tinyint(1)");
b.Property<bool>("IsEnabled")
.HasColumnType("tinyint(1)");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("varchar(100)");
b.Property<int>("Season")
.HasColumnType("int");
b.Property<int>("SortOrder")
.HasColumnType("int");
b.Property<DateOnly>("StartDate")
.HasColumnType("date");
b.Property<DateTime>("UpdatedAt")
.HasColumnType("datetime(6)");
b.HasKey("Id");
b.HasIndex("Code")
.IsUnique();
b.HasIndex("IsCurrent");
b.HasIndex("IsEnabled", "SortOrder");
b.ToTable("AcademicTerms");
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.AdministrativeClass", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("Code")
.IsRequired()
.HasMaxLength(40)
.HasColumnType("varchar(40)");
b.Property<string>("CounselorName")
.HasColumnType("longtext");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<int>("Grade")
.HasColumnType("int");
b.Property<bool>("IsEnabled")
.HasColumnType("tinyint(1)");
b.Property<Guid>("MajorId")
.HasColumnType("char(36)");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("varchar(100)");
b.Property<int>("SortOrder")
.HasColumnType("int");
b.Property<DateTime>("UpdatedAt")
.HasColumnType("datetime(6)");
b.HasKey("Id");
b.HasIndex("Code")
.IsUnique();
b.HasIndex("MajorId");
b.HasIndex("IsEnabled", "SortOrder");
b.ToTable("AdministrativeClasses");
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.Building", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<Guid>("CampusId")
.HasColumnType("char(36)");
b.Property<string>("Code")
.IsRequired()
.HasMaxLength(40)
.HasColumnType("varchar(40)");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<bool>("IsEnabled")
.HasColumnType("tinyint(1)");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("varchar(100)");
b.Property<int>("SortOrder")
.HasColumnType("int");
b.Property<DateTime>("UpdatedAt")
.HasColumnType("datetime(6)");
b.HasKey("Id");
b.HasIndex("CampusId");
b.HasIndex("Code")
.IsUnique();
b.HasIndex("IsEnabled", "SortOrder");
b.ToTable("Buildings");
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.Campus", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("Address")
.HasColumnType("longtext");
b.Property<string>("Code")
.IsRequired()
.HasMaxLength(40)
.HasColumnType("varchar(40)");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<bool>("IsEnabled")
.HasColumnType("tinyint(1)");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("varchar(100)");
b.Property<int>("SortOrder")
.HasColumnType("int");
b.Property<DateTime>("UpdatedAt")
.HasColumnType("datetime(6)");
b.HasKey("Id");
b.HasIndex("Code")
.IsUnique();
b.HasIndex("IsEnabled", "SortOrder");
b.ToTable("Campuses");
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.Classroom", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<Guid>("BuildingId")
.HasColumnType("char(36)");
b.Property<int>("Capacity")
.HasColumnType("int");
b.Property<string>("Code")
.IsRequired()
.HasMaxLength(40)
.HasColumnType("varchar(40)");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<string>("Equipment")
.HasColumnType("longtext");
b.Property<bool>("IsEnabled")
.HasColumnType("tinyint(1)");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("varchar(100)");
b.Property<string>("RoomType")
.IsRequired()
.HasColumnType("longtext");
b.Property<int>("SortOrder")
.HasColumnType("int");
b.Property<DateTime>("UpdatedAt")
.HasColumnType("datetime(6)");
b.HasKey("Id");
b.HasIndex("BuildingId");
b.HasIndex("Code")
.IsUnique();
b.HasIndex("IsEnabled", "SortOrder");
b.ToTable("Classrooms");
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.College", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<Guid?>("CampusId")
.HasColumnType("char(36)");
b.Property<string>("Code")
.IsRequired()
.HasMaxLength(40)
.HasColumnType("varchar(40)");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<bool>("IsEnabled")
.HasColumnType("tinyint(1)");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("varchar(100)");
b.Property<string>("ShortName")
.HasColumnType("longtext");
b.Property<int>("SortOrder")
.HasColumnType("int");
b.Property<DateTime>("UpdatedAt")
.HasColumnType("datetime(6)");
b.HasKey("Id");
b.HasIndex("CampusId");
b.HasIndex("Code")
.IsUnique();
b.HasIndex("IsEnabled", "SortOrder");
b.ToTable("Colleges");
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.Course", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<int>("AssessmentMethod")
.HasColumnType("int");
b.Property<string>("Code")
.IsRequired()
.HasMaxLength(40)
.HasColumnType("varchar(40)");
b.Property<Guid>("CollegeId")
.HasColumnType("char(36)");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<decimal>("Credits")
.HasPrecision(5, 2)
.HasColumnType("decimal(5,2)");
b.Property<string>("Description")
.HasMaxLength(1000)
.HasColumnType("varchar(1000)");
b.Property<string>("EnglishName")
.HasMaxLength(150)
.HasColumnType("varchar(150)");
b.Property<bool>("IsEnabled")
.HasColumnType("tinyint(1)");
b.Property<int>("LectureHours")
.HasColumnType("int");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("varchar(100)");
b.Property<int>("Nature")
.HasColumnType("int");
b.Property<int>("PracticeHours")
.HasColumnType("int");
b.Property<int>("SortOrder")
.HasColumnType("int");
b.Property<int>("TotalHours")
.HasColumnType("int");
b.Property<DateTime>("UpdatedAt")
.HasColumnType("datetime(6)");
b.HasKey("Id");
b.HasIndex("Code")
.IsUnique();
b.HasIndex("CollegeId", "Nature");
b.HasIndex("IsEnabled", "SortOrder");
b.ToTable("Courses");
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.Major", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("Code")
.IsRequired()
.HasMaxLength(40)
.HasColumnType("varchar(40)");
b.Property<Guid>("CollegeId")
.HasColumnType("char(36)");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<string>("DegreeType")
.IsRequired()
.HasColumnType("longtext");
b.Property<bool>("IsEnabled")
.HasColumnType("tinyint(1)");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("varchar(100)");
b.Property<int>("SchoolingYears")
.HasColumnType("int");
b.Property<int>("SortOrder")
.HasColumnType("int");
b.Property<DateTime>("UpdatedAt")
.HasColumnType("datetime(6)");
b.HasKey("Id");
b.HasIndex("Code")
.IsUnique();
b.HasIndex("CollegeId");
b.HasIndex("IsEnabled", "SortOrder");
b.ToTable("Majors");
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.Student", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<Guid>("AdministrativeClassId")
.HasColumnType("char(36)");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<DateOnly?>("DateOfBirth")
.HasColumnType("date");
b.Property<string>("Email")
.HasMaxLength(100)
.HasColumnType("varchar(100)");
b.Property<DateOnly>("EnrollmentDate")
.HasColumnType("date");
b.Property<int>("EnrollmentYear")
.HasColumnType("int");
b.Property<int>("Gender")
.HasColumnType("int");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)");
b.Property<string>("Notes")
.HasMaxLength(500)
.HasColumnType("varchar(500)");
b.Property<string>("Phone")
.HasMaxLength(30)
.HasColumnType("varchar(30)");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<string>("StudentNumber")
.IsRequired()
.HasMaxLength(30)
.HasColumnType("varchar(30)");
b.Property<DateTime>("UpdatedAt")
.HasColumnType("datetime(6)");
b.Property<Guid?>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("EnrollmentYear");
b.HasIndex("StudentNumber")
.IsUnique();
b.HasIndex("UserId");
b.HasIndex("AdministrativeClassId", "Status");
b.ToTable("Students");
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.Teacher", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<Guid>("CollegeId")
.HasColumnType("char(36)");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<string>("Email")
.HasMaxLength(100)
.HasColumnType("varchar(100)");
b.Property<int>("Gender")
.HasColumnType("int");
b.Property<DateOnly?>("HireDate")
.HasColumnType("date");
b.Property<bool>("IsExternal")
.HasColumnType("tinyint(1)");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)");
b.Property<string>("Notes")
.HasMaxLength(500)
.HasColumnType("varchar(500)");
b.Property<string>("Phone")
.HasMaxLength(30)
.HasColumnType("varchar(30)");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<string>("TeacherNumber")
.IsRequired()
.HasMaxLength(30)
.HasColumnType("varchar(30)");
b.Property<string>("Title")
.HasMaxLength(30)
.HasColumnType("varchar(30)");
b.Property<DateTime>("UpdatedAt")
.HasColumnType("datetime(6)");
b.Property<Guid?>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TeacherNumber")
.IsUnique();
b.HasIndex("UserId");
b.HasIndex("CollegeId", "Status");
b.ToTable("Teachers");
});
modelBuilder.Entity("Jiaowu.Api.Domain.Identity.ApplicationRole", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("longtext");
b.Property<int>("DataScope")
.HasColumnType("int");
b.Property<string>("Description")
.HasMaxLength(100)
.HasColumnType("varchar(100)");
b.Property<string>("Name")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("NormalizedName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique()
.HasDatabaseName("RoleNameIndex");
b.ToTable("AspNetRoles", (string)null);
});
modelBuilder.Entity("Jiaowu.Api.Domain.Identity.ApplicationUser", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<int>("AccessFailedCount")
.HasColumnType("int");
b.Property<Guid?>("CollegeId")
.HasColumnType("char(36)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("longtext");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<string>("DisplayName")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)");
b.Property<string>("Email")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<bool>("EmailConfirmed")
.HasColumnType("tinyint(1)");
b.Property<bool>("IsEnabled")
.HasColumnType("tinyint(1)");
b.Property<DateTime?>("LastLoginAt")
.HasColumnType("datetime(6)");
b.Property<bool>("LockoutEnabled")
.HasColumnType("tinyint(1)");
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("datetime");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("NormalizedUserName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("PasswordHash")
.HasColumnType("longtext");
b.Property<string>("PhoneNumber")
.HasColumnType("longtext");
b.Property<bool>("PhoneNumberConfirmed")
.HasColumnType("tinyint(1)");
b.Property<string>("SecurityStamp")
.HasColumnType("longtext");
b.Property<string>("StaffNumber")
.HasMaxLength(30)
.HasColumnType("varchar(30)");
b.Property<bool>("TwoFactorEnabled")
.HasColumnType("tinyint(1)");
b.Property<string>("UserName")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasDatabaseName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasDatabaseName("UserNameIndex");
b.HasIndex("StaffNumber");
b.ToTable("AspNetUsers", (string)null);
});
modelBuilder.Entity("Jiaowu.Api.Domain.System.AuditLog", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<string>("IpAddress")
.HasMaxLength(64)
.HasColumnType("varchar(64)");
b.Property<string>("Method")
.IsRequired()
.HasMaxLength(10)
.HasColumnType("varchar(10)");
b.Property<string>("Path")
.IsRequired()
.HasMaxLength(300)
.HasColumnType("varchar(300)");
b.Property<int>("StatusCode")
.HasColumnType("int");
b.Property<DateTime>("UpdatedAt")
.HasColumnType("datetime(6)");
b.Property<Guid?>("UserId")
.HasColumnType("char(36)");
b.Property<string>("UserName")
.HasMaxLength(100)
.HasColumnType("varchar(100)");
b.HasKey("Id");
b.HasIndex("CreatedAt");
b.ToTable("AuditLogs");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<System.Guid>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("ClaimType")
.HasColumnType("longtext");
b.Property<string>("ClaimValue")
.HasColumnType("longtext");
b.Property<Guid>("RoleId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<System.Guid>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("ClaimType")
.HasColumnType("longtext");
b.Property<string>("ClaimValue")
.HasColumnType("longtext");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<System.Guid>", b =>
{
b.Property<string>("LoginProvider")
.HasColumnType("varchar(255)");
b.Property<string>("ProviderKey")
.HasColumnType("varchar(255)");
b.Property<string>("ProviderDisplayName")
.HasColumnType("longtext");
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<System.Guid>", b =>
{
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.Property<Guid>("RoleId")
.HasColumnType("char(36)");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<System.Guid>", b =>
{
b.Property<Guid>("UserId")
.HasColumnType("char(36)");
b.Property<string>("LoginProvider")
.HasColumnType("varchar(255)");
b.Property<string>("Name")
.HasColumnType("varchar(255)");
b.Property<string>("Value")
.HasColumnType("longtext");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens", (string)null);
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.AdministrativeClass", b =>
{
b.HasOne("Jiaowu.Api.Domain.Academic.Major", "Major")
.WithMany()
.HasForeignKey("MajorId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.Navigation("Major");
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.Building", b =>
{
b.HasOne("Jiaowu.Api.Domain.Academic.Campus", "Campus")
.WithMany()
.HasForeignKey("CampusId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.Navigation("Campus");
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.Classroom", b =>
{
b.HasOne("Jiaowu.Api.Domain.Academic.Building", "Building")
.WithMany()
.HasForeignKey("BuildingId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.Navigation("Building");
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.College", b =>
{
b.HasOne("Jiaowu.Api.Domain.Academic.Campus", "Campus")
.WithMany()
.HasForeignKey("CampusId")
.OnDelete(DeleteBehavior.Restrict);
b.Navigation("Campus");
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.Course", b =>
{
b.HasOne("Jiaowu.Api.Domain.Academic.College", "College")
.WithMany()
.HasForeignKey("CollegeId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.Navigation("College");
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.Major", b =>
{
b.HasOne("Jiaowu.Api.Domain.Academic.College", "College")
.WithMany()
.HasForeignKey("CollegeId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.Navigation("College");
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.Student", b =>
{
b.HasOne("Jiaowu.Api.Domain.Academic.AdministrativeClass", "AdministrativeClass")
.WithMany()
.HasForeignKey("AdministrativeClassId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("Jiaowu.Api.Domain.Identity.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.SetNull);
b.Navigation("AdministrativeClass");
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.Teacher", b =>
{
b.HasOne("Jiaowu.Api.Domain.Academic.College", "College")
.WithMany()
.HasForeignKey("CollegeId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("Jiaowu.Api.Domain.Identity.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.SetNull);
b.Navigation("College");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<System.Guid>", b =>
{
b.HasOne("Jiaowu.Api.Domain.Identity.ApplicationRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<System.Guid>", b =>
{
b.HasOne("Jiaowu.Api.Domain.Identity.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<System.Guid>", b =>
{
b.HasOne("Jiaowu.Api.Domain.Identity.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<System.Guid>", b =>
{
b.HasOne("Jiaowu.Api.Domain.Identity.ApplicationRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Jiaowu.Api.Domain.Identity.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<System.Guid>", b =>
{
b.HasOne("Jiaowu.Api.Domain.Identity.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
#pragma warning restore 612, 618
}
}
}
@@ -0,0 +1,190 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
{
/// <inheritdoc />
public partial class PeopleAndCourses : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Courses",
columns: table => new
{
Id = table.Column<Guid>(type: "char(36)", nullable: false),
CollegeId = table.Column<Guid>(type: "char(36)", nullable: false),
EnglishName = table.Column<string>(type: "varchar(150)", maxLength: 150, nullable: true),
Credits = table.Column<decimal>(type: "decimal(5,2)", precision: 5, scale: 2, nullable: false),
TotalHours = table.Column<int>(type: "int", nullable: false),
LectureHours = table.Column<int>(type: "int", nullable: false),
PracticeHours = table.Column<int>(type: "int", nullable: false),
Nature = table.Column<int>(type: "int", nullable: false),
AssessmentMethod = table.Column<int>(type: "int", nullable: false),
Description = table.Column<string>(type: "varchar(1000)", maxLength: 1000, nullable: true),
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
UpdatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
Code = table.Column<string>(type: "varchar(40)", maxLength: 40, nullable: false),
Name = table.Column<string>(type: "varchar(100)", maxLength: 100, nullable: false),
SortOrder = table.Column<int>(type: "int", nullable: false),
IsEnabled = table.Column<bool>(type: "tinyint(1)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Courses", x => x.Id);
table.ForeignKey(
name: "FK_Courses_Colleges_CollegeId",
column: x => x.CollegeId,
principalTable: "Colleges",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
})
.Annotation("MySQL:Charset", "utf8mb4");
migrationBuilder.CreateTable(
name: "Students",
columns: table => new
{
Id = table.Column<Guid>(type: "char(36)", nullable: false),
StudentNumber = table.Column<string>(type: "varchar(30)", maxLength: 30, nullable: false),
Name = table.Column<string>(type: "varchar(50)", maxLength: 50, nullable: false),
Gender = table.Column<int>(type: "int", nullable: false),
AdministrativeClassId = table.Column<Guid>(type: "char(36)", nullable: false),
EnrollmentYear = table.Column<int>(type: "int", nullable: false),
EnrollmentDate = table.Column<DateOnly>(type: "date", nullable: false),
Status = table.Column<int>(type: "int", nullable: false),
DateOfBirth = table.Column<DateOnly>(type: "date", nullable: true),
Phone = table.Column<string>(type: "varchar(30)", maxLength: 30, nullable: true),
Email = table.Column<string>(type: "varchar(100)", maxLength: 100, nullable: true),
Notes = table.Column<string>(type: "varchar(500)", maxLength: 500, nullable: true),
UserId = table.Column<Guid>(type: "char(36)", 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_Students", x => x.Id);
table.ForeignKey(
name: "FK_Students_AdministrativeClasses_AdministrativeClassId",
column: x => x.AdministrativeClassId,
principalTable: "AdministrativeClasses",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_Students_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.SetNull);
})
.Annotation("MySQL:Charset", "utf8mb4");
migrationBuilder.CreateTable(
name: "Teachers",
columns: table => new
{
Id = table.Column<Guid>(type: "char(36)", nullable: false),
TeacherNumber = table.Column<string>(type: "varchar(30)", maxLength: 30, nullable: false),
Name = table.Column<string>(type: "varchar(50)", maxLength: 50, nullable: false),
Gender = table.Column<int>(type: "int", nullable: false),
CollegeId = table.Column<Guid>(type: "char(36)", nullable: false),
Title = table.Column<string>(type: "varchar(30)", maxLength: 30, nullable: true),
Status = table.Column<int>(type: "int", nullable: false),
HireDate = table.Column<DateOnly>(type: "date", nullable: true),
IsExternal = table.Column<bool>(type: "tinyint(1)", nullable: false),
Phone = table.Column<string>(type: "varchar(30)", maxLength: 30, nullable: true),
Email = table.Column<string>(type: "varchar(100)", maxLength: 100, nullable: true),
Notes = table.Column<string>(type: "varchar(500)", maxLength: 500, nullable: true),
UserId = table.Column<Guid>(type: "char(36)", 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_Teachers", x => x.Id);
table.ForeignKey(
name: "FK_Teachers_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.SetNull);
table.ForeignKey(
name: "FK_Teachers_Colleges_CollegeId",
column: x => x.CollegeId,
principalTable: "Colleges",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
})
.Annotation("MySQL:Charset", "utf8mb4");
migrationBuilder.CreateIndex(
name: "IX_Courses_Code",
table: "Courses",
column: "Code",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_Courses_CollegeId_Nature",
table: "Courses",
columns: new[] { "CollegeId", "Nature" });
migrationBuilder.CreateIndex(
name: "IX_Courses_IsEnabled_SortOrder",
table: "Courses",
columns: new[] { "IsEnabled", "SortOrder" });
migrationBuilder.CreateIndex(
name: "IX_Students_AdministrativeClassId_Status",
table: "Students",
columns: new[] { "AdministrativeClassId", "Status" });
migrationBuilder.CreateIndex(
name: "IX_Students_EnrollmentYear",
table: "Students",
column: "EnrollmentYear");
migrationBuilder.CreateIndex(
name: "IX_Students_StudentNumber",
table: "Students",
column: "StudentNumber",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_Students_UserId",
table: "Students",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_Teachers_CollegeId_Status",
table: "Teachers",
columns: new[] { "CollegeId", "Status" });
migrationBuilder.CreateIndex(
name: "IX_Teachers_TeacherNumber",
table: "Teachers",
column: "TeacherNumber",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_Teachers_UserId",
table: "Teachers",
column: "UserId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Courses");
migrationBuilder.DropTable(
name: "Students");
migrationBuilder.DropTable(
name: "Teachers");
}
}
}
@@ -72,7 +72,7 @@ namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
b.HasIndex("IsEnabled", "SortOrder");
b.ToTable("AcademicTerms");
b.ToTable("AcademicTerms", (string)null);
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.AdministrativeClass", b =>
@@ -121,7 +121,7 @@ namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
b.HasIndex("IsEnabled", "SortOrder");
b.ToTable("AdministrativeClasses");
b.ToTable("AdministrativeClasses", (string)null);
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.Building", b =>
@@ -164,7 +164,7 @@ namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
b.HasIndex("IsEnabled", "SortOrder");
b.ToTable("Buildings");
b.ToTable("Buildings", (string)null);
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.Campus", b =>
@@ -205,7 +205,7 @@ namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
b.HasIndex("IsEnabled", "SortOrder");
b.ToTable("Campuses");
b.ToTable("Campuses", (string)null);
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.Classroom", b =>
@@ -258,7 +258,7 @@ namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
b.HasIndex("IsEnabled", "SortOrder");
b.ToTable("Classrooms");
b.ToTable("Classrooms", (string)null);
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.College", b =>
@@ -304,7 +304,77 @@ namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
b.HasIndex("IsEnabled", "SortOrder");
b.ToTable("Colleges");
b.ToTable("Colleges", (string)null);
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.Course", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<int>("AssessmentMethod")
.HasColumnType("int");
b.Property<string>("Code")
.IsRequired()
.HasMaxLength(40)
.HasColumnType("varchar(40)");
b.Property<Guid>("CollegeId")
.HasColumnType("char(36)");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<decimal>("Credits")
.HasPrecision(5, 2)
.HasColumnType("decimal(5,2)");
b.Property<string>("Description")
.HasMaxLength(1000)
.HasColumnType("varchar(1000)");
b.Property<string>("EnglishName")
.HasMaxLength(150)
.HasColumnType("varchar(150)");
b.Property<bool>("IsEnabled")
.HasColumnType("tinyint(1)");
b.Property<int>("LectureHours")
.HasColumnType("int");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("varchar(100)");
b.Property<int>("Nature")
.HasColumnType("int");
b.Property<int>("PracticeHours")
.HasColumnType("int");
b.Property<int>("SortOrder")
.HasColumnType("int");
b.Property<int>("TotalHours")
.HasColumnType("int");
b.Property<DateTime>("UpdatedAt")
.HasColumnType("datetime(6)");
b.HasKey("Id");
b.HasIndex("Code")
.IsUnique();
b.HasIndex("CollegeId", "Nature");
b.HasIndex("IsEnabled", "SortOrder");
b.ToTable("Courses", (string)null);
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.Major", b =>
@@ -354,7 +424,144 @@ namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
b.HasIndex("IsEnabled", "SortOrder");
b.ToTable("Majors");
b.ToTable("Majors", (string)null);
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.Student", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<Guid>("AdministrativeClassId")
.HasColumnType("char(36)");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<DateOnly?>("DateOfBirth")
.HasColumnType("date");
b.Property<string>("Email")
.HasMaxLength(100)
.HasColumnType("varchar(100)");
b.Property<DateOnly>("EnrollmentDate")
.HasColumnType("date");
b.Property<int>("EnrollmentYear")
.HasColumnType("int");
b.Property<int>("Gender")
.HasColumnType("int");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)");
b.Property<string>("Notes")
.HasMaxLength(500)
.HasColumnType("varchar(500)");
b.Property<string>("Phone")
.HasMaxLength(30)
.HasColumnType("varchar(30)");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<string>("StudentNumber")
.IsRequired()
.HasMaxLength(30)
.HasColumnType("varchar(30)");
b.Property<DateTime>("UpdatedAt")
.HasColumnType("datetime(6)");
b.Property<Guid?>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("EnrollmentYear");
b.HasIndex("StudentNumber")
.IsUnique();
b.HasIndex("UserId");
b.HasIndex("AdministrativeClassId", "Status");
b.ToTable("Students", (string)null);
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.Teacher", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<Guid>("CollegeId")
.HasColumnType("char(36)");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<string>("Email")
.HasMaxLength(100)
.HasColumnType("varchar(100)");
b.Property<int>("Gender")
.HasColumnType("int");
b.Property<DateOnly?>("HireDate")
.HasColumnType("date");
b.Property<bool>("IsExternal")
.HasColumnType("tinyint(1)");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)");
b.Property<string>("Notes")
.HasMaxLength(500)
.HasColumnType("varchar(500)");
b.Property<string>("Phone")
.HasMaxLength(30)
.HasColumnType("varchar(30)");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<string>("TeacherNumber")
.IsRequired()
.HasMaxLength(30)
.HasColumnType("varchar(30)");
b.Property<string>("Title")
.HasMaxLength(30)
.HasColumnType("varchar(30)");
b.Property<DateTime>("UpdatedAt")
.HasColumnType("datetime(6)");
b.Property<Guid?>("UserId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("TeacherNumber")
.IsUnique();
b.HasIndex("UserId");
b.HasIndex("CollegeId", "Status");
b.ToTable("Teachers", (string)null);
});
modelBuilder.Entity("Jiaowu.Api.Domain.Identity.ApplicationRole", b =>
@@ -519,7 +726,7 @@ namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
b.HasIndex("CreatedAt");
b.ToTable("AuditLogs");
b.ToTable("AuditLogs", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<System.Guid>", b =>
@@ -664,6 +871,17 @@ namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
b.Navigation("Campus");
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.Course", b =>
{
b.HasOne("Jiaowu.Api.Domain.Academic.College", "College")
.WithMany()
.HasForeignKey("CollegeId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.Navigation("College");
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.Major", b =>
{
b.HasOne("Jiaowu.Api.Domain.Academic.College", "College")
@@ -675,6 +893,38 @@ namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
b.Navigation("College");
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.Student", b =>
{
b.HasOne("Jiaowu.Api.Domain.Academic.AdministrativeClass", "AdministrativeClass")
.WithMany()
.HasForeignKey("AdministrativeClassId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("Jiaowu.Api.Domain.Identity.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.SetNull);
b.Navigation("AdministrativeClass");
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.Teacher", b =>
{
b.HasOne("Jiaowu.Api.Domain.Academic.College", "College")
.WithMany()
.HasForeignKey("CollegeId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("Jiaowu.Api.Domain.Identity.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.SetNull);
b.Navigation("College");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<System.Guid>", b =>
{
b.HasOne("Jiaowu.Api.Domain.Identity.ApplicationRole", null)