From 826eac1372690f9a8060af542f7f63f59506fb07 Mon Sep 17 00:00:00 2001 From: James Kolpack Date: Thu, 4 Dec 2025 08:09:01 -0500 Subject: [PATCH] Database improvement 1. Separate configuration files 2. Remove commented code 3. Improve entity configurations (constraints, indexes, relationships) --- Data/AppDbContext.cs | 60 ---- .../EventDefinitionConfiguration.cs | 47 +++ Data/Configurations/StudentConfiguration.cs | 60 ++++ .../StudentEventRankingConfiguration.cs | 33 ++ Data/Configurations/TeamConfiguration.cs | 37 +++ ...04130505_ConfigurationRefactor.Designer.cs | 279 +++++++++++++++++ .../20251204130505_ConfigurationRefactor.cs | 287 ++++++++++++++++++ Data/Migrations/AppDbContextModelSnapshot.cs | 64 ++-- 8 files changed, 787 insertions(+), 80 deletions(-) create mode 100644 Data/Configurations/EventDefinitionConfiguration.cs create mode 100644 Data/Configurations/StudentConfiguration.cs create mode 100644 Data/Configurations/StudentEventRankingConfiguration.cs create mode 100644 Data/Configurations/TeamConfiguration.cs create mode 100644 Data/Migrations/20251204130505_ConfigurationRefactor.Designer.cs create mode 100644 Data/Migrations/20251204130505_ConfigurationRefactor.cs diff --git a/Data/AppDbContext.cs b/Data/AppDbContext.cs index 230004f..f6ca913 100644 --- a/Data/AppDbContext.cs +++ b/Data/AppDbContext.cs @@ -1,7 +1,6 @@ using System.Reflection; using Core.Entities; using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; namespace Data { @@ -24,64 +23,5 @@ namespace Data { modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly()); } - - //protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - //{ - // var dbPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ChapterOrganizer.db"); - // optionsBuilder.UseSqlite($"Data Source={dbPath}"); - //} - } - - public class EventDefinitionConfiguration : IEntityTypeConfiguration - { - public void Configure(EntityTypeBuilder builder) - { - builder.HasKey(u => u.Id); - - builder.HasIndex(u => u.Name); - builder.Property(u => u.Name).HasMaxLength(128); - - //builder.HasMany(u => u.Roles) - // .WithOne() - // .HasForeignKey(r => r.Id) - // .OnDelete(DeleteBehavior.Restrict); - } - } - - public class StudentConfiguration : IEntityTypeConfiguration - { - public void Configure(EntityTypeBuilder builder) - { - builder.HasKey(u => u.Id); - //builder.Property(s => s.Grade); - - builder - .HasMany(e => e.RankedEvents) - .WithMany() - .UsingEntity() - .HasOne(e => e.EventDefinition); - } - } - - public class TeamConfiguration : IEntityTypeConfiguration - { - public void Configure(EntityTypeBuilder builder) - { - builder.HasKey(u => u.Id); - - builder.HasMany(e => e.Students) - .WithMany(e => e.Teams); - - builder.HasOne(e => e.Captain); - - } - } - public class StudentEventRankingConfiguration : IEntityTypeConfiguration - { - public void Configure(EntityTypeBuilder builder) - { - //builder.HasKey(u => u.EventDefinitionId); - //builder.HasKey(u => u.StudentId); - } } } diff --git a/Data/Configurations/EventDefinitionConfiguration.cs b/Data/Configurations/EventDefinitionConfiguration.cs new file mode 100644 index 0000000..b68a762 --- /dev/null +++ b/Data/Configurations/EventDefinitionConfiguration.cs @@ -0,0 +1,47 @@ +using Core.Entities; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace Data.Configurations +{ + public class EventDefinitionConfiguration : IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder builder) + { + builder.HasKey(e => e.Id); + + // Indexes + builder.HasIndex(e => e.Name).IsUnique(); + builder.HasIndex(e => e.EventFormat); + + // Constraints + builder.Property(e => e.Name) + .IsRequired() + .HasMaxLength(128); + + builder.Property(e => e.ShortName) + .HasMaxLength(50); + + builder.Property(e => e.Description) + .HasMaxLength(1000); + + builder.Property(e => e.Theme) + .HasMaxLength(500); + + builder.Property(e => e.Eligibility) + .IsRequired() + .HasMaxLength(200); + + builder.Property(e => e.SemifinalistActivity) + .HasMaxLength(500); + + builder.Property(e => e.Documentation) + .HasMaxLength(500); + + // Value conversions for enums + builder.Property(e => e.EventFormat) + .HasConversion() + .HasMaxLength(50); + } + } +} diff --git a/Data/Configurations/StudentConfiguration.cs b/Data/Configurations/StudentConfiguration.cs new file mode 100644 index 0000000..30421c9 --- /dev/null +++ b/Data/Configurations/StudentConfiguration.cs @@ -0,0 +1,60 @@ +using Core.Entities; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace Data.Configurations +{ + public class StudentConfiguration : IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder builder) + { + builder.HasKey(s => s.Id); + + // Indexes + builder.HasIndex(s => new { s.FirstName, s.LastName }); + builder.HasIndex(s => s.Email); + builder.HasIndex(s => s.Grade); + + // Constraints + builder.Property(s => s.FirstName) + .IsRequired() + .HasMaxLength(100); + + builder.Property(s => s.LastName) + .IsRequired() + .HasMaxLength(100); + + builder.Property(s => s.Email) + .HasMaxLength(255); + + builder.Property(s => s.PhoneNumber) + .HasMaxLength(20); + + builder.Property(s => s.RegionalId) + .HasMaxLength(50); + + builder.Property(s => s.StateId) + .HasMaxLength(50); + + builder.Property(s => s.NationalId) + .HasMaxLength(50); + + // Value conversion for enum + builder.Property(s => s.OfficerRole) + .HasConversion() + .HasMaxLength(50); + + // Relationships + // Configure the collection navigation to the join entity + builder.HasMany(s => s.EventRankings) + .WithOne(r => r.Student) + .IsRequired() + .OnDelete(DeleteBehavior.Cascade); + + // Many-to-many through StudentEventRanking + builder.HasMany(s => s.RankedEvents) + .WithMany() + .UsingEntity(); + } + } +} diff --git a/Data/Configurations/StudentEventRankingConfiguration.cs b/Data/Configurations/StudentEventRankingConfiguration.cs new file mode 100644 index 0000000..8c31bfc --- /dev/null +++ b/Data/Configurations/StudentEventRankingConfiguration.cs @@ -0,0 +1,33 @@ +using Core.Entities; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace Data.Configurations +{ + public class StudentEventRankingConfiguration : IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder builder) + { + // Note: Relationships are configured in StudentConfiguration + // This configuration only defines keys, indexes, and constraints + + // Composite key on shadow properties created by EF Core + builder.HasKey("StudentId", "EventDefinitionId"); + + // Indexes on shadow properties + builder.HasIndex(r => r.Rank); + builder.HasIndex("StudentId"); + builder.HasIndex("EventDefinitionId"); + + // Constraints + builder.Property(r => r.Rank) + .IsRequired(); + + // Relationship to EventDefinition (Student relationship is in StudentConfiguration) + builder.HasOne(r => r.EventDefinition) + .WithMany() + .IsRequired() + .OnDelete(DeleteBehavior.Cascade); + } + } +} diff --git a/Data/Configurations/TeamConfiguration.cs b/Data/Configurations/TeamConfiguration.cs new file mode 100644 index 0000000..2abedf7 --- /dev/null +++ b/Data/Configurations/TeamConfiguration.cs @@ -0,0 +1,37 @@ +using Core.Entities; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace Data.Configurations +{ + public class TeamConfiguration : IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder builder) + { + builder.HasKey(t => t.Id); + + // Indexes on shadow properties created by EF Core + builder.HasIndex("EventId"); + builder.HasIndex("EventId", "Identifier"); + + // Constraints + builder.Property(t => t.Identifier) + .HasMaxLength(50); + + // Relationships + builder.HasOne(t => t.Event) + .WithMany() + .IsRequired() + .OnDelete(DeleteBehavior.Restrict); // Don't delete teams when event is deleted + + builder.HasMany(t => t.Students) + .WithMany(s => s.Teams) + .UsingEntity(j => j.ToTable("TeamStudents")); // Explicit table name + + builder.HasOne(t => t.Captain) + .WithMany() + .IsRequired(false) + .OnDelete(DeleteBehavior.SetNull); // Set to null if captain is deleted + } + } +} diff --git a/Data/Migrations/20251204130505_ConfigurationRefactor.Designer.cs b/Data/Migrations/20251204130505_ConfigurationRefactor.Designer.cs new file mode 100644 index 0000000..a8e8e09 --- /dev/null +++ b/Data/Migrations/20251204130505_ConfigurationRefactor.Designer.cs @@ -0,0 +1,279 @@ +// +using Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Data.Migrations +{ + [DbContext(typeof(AppDbContext))] + [Migration("20251204130505_ConfigurationRefactor")] + partial class ConfigurationRefactor + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "9.0.8"); + + modelBuilder.Entity("Core.Entities.EventDefinition", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ChapterEligibilityCountRegionals") + .HasColumnType("INTEGER"); + + b.Property("ChapterEligibilityCountState") + .HasColumnType("INTEGER"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("Documentation") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("Eligibility") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("EventFormat") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("LevelOfEffort") + .HasColumnType("INTEGER"); + + b.Property("MaxTeamSize") + .HasColumnType("INTEGER"); + + b.Property("MinTeamSize") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("Notes") + .HasMaxLength(1024) + .HasColumnType("TEXT"); + + b.Property("OnSiteActivity") + .HasColumnType("INTEGER"); + + b.Property("Presubmission") + .HasColumnType("INTEGER"); + + b.Property("SemifinalistActivity") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("ShortName") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("Theme") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("EventFormat"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("Events"); + }); + + modelBuilder.Entity("Core.Entities.Student", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Email") + .HasMaxLength(255) + .HasColumnType("TEXT"); + + b.Property("FirstName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Grade") + .HasColumnType("INTEGER"); + + b.Property("LastName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("NationalId") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("OfficerRole") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("RegionalId") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("StateId") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("TsaYear") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("Email"); + + b.HasIndex("Grade"); + + b.HasIndex("FirstName", "LastName"); + + b.ToTable("Students"); + }); + + modelBuilder.Entity("Core.Entities.StudentEventRanking", b => + { + b.Property("StudentId") + .HasColumnType("INTEGER"); + + b.Property("EventDefinitionId") + .HasColumnType("INTEGER"); + + b.Property("Rank") + .HasColumnType("INTEGER"); + + b.HasKey("StudentId", "EventDefinitionId"); + + b.HasIndex("EventDefinitionId"); + + b.HasIndex("Rank"); + + b.HasIndex("StudentId"); + + b.ToTable("StudentEventRanking"); + }); + + modelBuilder.Entity("Core.Entities.Team", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CaptainId") + .HasColumnType("INTEGER"); + + b.Property("EventId") + .HasColumnType("INTEGER"); + + b.Property("Identifier") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("CaptainId"); + + b.HasIndex("EventId"); + + b.HasIndex("EventId", "Identifier"); + + b.ToTable("Teams"); + }); + + modelBuilder.Entity("StudentTeam", b => + { + b.Property("StudentsId") + .HasColumnType("INTEGER"); + + b.Property("TeamsId") + .HasColumnType("INTEGER"); + + b.HasKey("StudentsId", "TeamsId"); + + b.HasIndex("TeamsId"); + + b.ToTable("TeamStudents", (string)null); + }); + + modelBuilder.Entity("Core.Entities.StudentEventRanking", b => + { + b.HasOne("Core.Entities.EventDefinition", "EventDefinition") + .WithMany() + .HasForeignKey("EventDefinitionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Core.Entities.Student", "Student") + .WithMany("EventRankings") + .HasForeignKey("StudentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("EventDefinition"); + + b.Navigation("Student"); + }); + + modelBuilder.Entity("Core.Entities.Team", b => + { + b.HasOne("Core.Entities.Student", "Captain") + .WithMany() + .HasForeignKey("CaptainId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Core.Entities.EventDefinition", "Event") + .WithMany() + .HasForeignKey("EventId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Captain"); + + b.Navigation("Event"); + }); + + modelBuilder.Entity("StudentTeam", b => + { + b.HasOne("Core.Entities.Student", null) + .WithMany() + .HasForeignKey("StudentsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Core.Entities.Team", null) + .WithMany() + .HasForeignKey("TeamsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Core.Entities.Student", b => + { + b.Navigation("EventRankings"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Data/Migrations/20251204130505_ConfigurationRefactor.cs b/Data/Migrations/20251204130505_ConfigurationRefactor.cs new file mode 100644 index 0000000..7851fef --- /dev/null +++ b/Data/Migrations/20251204130505_ConfigurationRefactor.cs @@ -0,0 +1,287 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Data.Migrations +{ + /// + public partial class ConfigurationRefactor : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_StudentTeam_Students_StudentsId", + table: "StudentTeam"); + + migrationBuilder.DropForeignKey( + name: "FK_StudentTeam_Teams_TeamsId", + table: "StudentTeam"); + + migrationBuilder.DropForeignKey( + name: "FK_Teams_Events_EventId", + table: "Teams"); + + migrationBuilder.DropForeignKey( + name: "FK_Teams_Students_CaptainId", + table: "Teams"); + + migrationBuilder.DropPrimaryKey( + name: "PK_StudentEventRanking", + table: "StudentEventRanking"); + + migrationBuilder.DropIndex( + name: "IX_Events_Name", + table: "Events"); + + migrationBuilder.DropPrimaryKey( + name: "PK_StudentTeam", + table: "StudentTeam"); + + migrationBuilder.RenameTable( + name: "StudentTeam", + newName: "TeamStudents"); + + migrationBuilder.RenameIndex( + name: "IX_StudentTeam_TeamsId", + table: "TeamStudents", + newName: "IX_TeamStudents_TeamsId"); + + migrationBuilder.AlterColumn( + name: "OfficerRole", + table: "Students", + type: "TEXT", + maxLength: 50, + nullable: true, + oldClrType: typeof(int), + oldType: "INTEGER", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "EventFormat", + table: "Events", + type: "TEXT", + maxLength: 50, + nullable: false, + oldClrType: typeof(int), + oldType: "INTEGER"); + + migrationBuilder.AddPrimaryKey( + name: "PK_StudentEventRanking", + table: "StudentEventRanking", + columns: new[] { "StudentId", "EventDefinitionId" }); + + migrationBuilder.AddPrimaryKey( + name: "PK_TeamStudents", + table: "TeamStudents", + columns: new[] { "StudentsId", "TeamsId" }); + + migrationBuilder.CreateIndex( + name: "IX_Teams_EventId_Identifier", + table: "Teams", + columns: new[] { "EventId", "Identifier" }); + + migrationBuilder.CreateIndex( + name: "IX_Students_Email", + table: "Students", + column: "Email"); + + migrationBuilder.CreateIndex( + name: "IX_Students_FirstName_LastName", + table: "Students", + columns: new[] { "FirstName", "LastName" }); + + migrationBuilder.CreateIndex( + name: "IX_Students_Grade", + table: "Students", + column: "Grade"); + + migrationBuilder.CreateIndex( + name: "IX_StudentEventRanking_EventDefinitionId", + table: "StudentEventRanking", + column: "EventDefinitionId"); + + migrationBuilder.CreateIndex( + name: "IX_StudentEventRanking_Rank", + table: "StudentEventRanking", + column: "Rank"); + + migrationBuilder.CreateIndex( + name: "IX_Events_EventFormat", + table: "Events", + column: "EventFormat"); + + migrationBuilder.CreateIndex( + name: "IX_Events_Name", + table: "Events", + column: "Name", + unique: true); + + migrationBuilder.AddForeignKey( + name: "FK_Teams_Events_EventId", + table: "Teams", + column: "EventId", + principalTable: "Events", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + + migrationBuilder.AddForeignKey( + name: "FK_Teams_Students_CaptainId", + table: "Teams", + column: "CaptainId", + principalTable: "Students", + principalColumn: "Id", + onDelete: ReferentialAction.SetNull); + + migrationBuilder.AddForeignKey( + name: "FK_TeamStudents_Students_StudentsId", + table: "TeamStudents", + column: "StudentsId", + principalTable: "Students", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_TeamStudents_Teams_TeamsId", + table: "TeamStudents", + column: "TeamsId", + principalTable: "Teams", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Teams_Events_EventId", + table: "Teams"); + + migrationBuilder.DropForeignKey( + name: "FK_Teams_Students_CaptainId", + table: "Teams"); + + migrationBuilder.DropForeignKey( + name: "FK_TeamStudents_Students_StudentsId", + table: "TeamStudents"); + + migrationBuilder.DropForeignKey( + name: "FK_TeamStudents_Teams_TeamsId", + table: "TeamStudents"); + + migrationBuilder.DropIndex( + name: "IX_Teams_EventId_Identifier", + table: "Teams"); + + migrationBuilder.DropIndex( + name: "IX_Students_Email", + table: "Students"); + + migrationBuilder.DropIndex( + name: "IX_Students_FirstName_LastName", + table: "Students"); + + migrationBuilder.DropIndex( + name: "IX_Students_Grade", + table: "Students"); + + migrationBuilder.DropPrimaryKey( + name: "PK_StudentEventRanking", + table: "StudentEventRanking"); + + migrationBuilder.DropIndex( + name: "IX_StudentEventRanking_EventDefinitionId", + table: "StudentEventRanking"); + + migrationBuilder.DropIndex( + name: "IX_StudentEventRanking_Rank", + table: "StudentEventRanking"); + + migrationBuilder.DropIndex( + name: "IX_Events_EventFormat", + table: "Events"); + + migrationBuilder.DropIndex( + name: "IX_Events_Name", + table: "Events"); + + migrationBuilder.DropPrimaryKey( + name: "PK_TeamStudents", + table: "TeamStudents"); + + migrationBuilder.RenameTable( + name: "TeamStudents", + newName: "StudentTeam"); + + migrationBuilder.RenameIndex( + name: "IX_TeamStudents_TeamsId", + table: "StudentTeam", + newName: "IX_StudentTeam_TeamsId"); + + migrationBuilder.AlterColumn( + name: "OfficerRole", + table: "Students", + type: "INTEGER", + nullable: true, + oldClrType: typeof(string), + oldType: "TEXT", + oldMaxLength: 50, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "EventFormat", + table: "Events", + type: "INTEGER", + nullable: false, + oldClrType: typeof(string), + oldType: "TEXT", + oldMaxLength: 50); + + migrationBuilder.AddPrimaryKey( + name: "PK_StudentEventRanking", + table: "StudentEventRanking", + columns: new[] { "EventDefinitionId", "StudentId" }); + + migrationBuilder.AddPrimaryKey( + name: "PK_StudentTeam", + table: "StudentTeam", + columns: new[] { "StudentsId", "TeamsId" }); + + migrationBuilder.CreateIndex( + name: "IX_Events_Name", + table: "Events", + column: "Name"); + + migrationBuilder.AddForeignKey( + name: "FK_StudentTeam_Students_StudentsId", + table: "StudentTeam", + column: "StudentsId", + principalTable: "Students", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_StudentTeam_Teams_TeamsId", + table: "StudentTeam", + column: "TeamsId", + principalTable: "Teams", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_Teams_Events_EventId", + table: "Teams", + column: "EventId", + principalTable: "Events", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_Teams_Students_CaptainId", + table: "Teams", + column: "CaptainId", + principalTable: "Students", + principalColumn: "Id"); + } + } +} diff --git a/Data/Migrations/AppDbContextModelSnapshot.cs b/Data/Migrations/AppDbContextModelSnapshot.cs index 998262d..e3c7d3b 100644 --- a/Data/Migrations/AppDbContextModelSnapshot.cs +++ b/Data/Migrations/AppDbContextModelSnapshot.cs @@ -29,20 +29,22 @@ namespace Data.Migrations .HasColumnType("INTEGER"); b.Property("Description") - .HasMaxLength(1024) + .HasMaxLength(1000) .HasColumnType("TEXT"); b.Property("Documentation") - .HasMaxLength(64) + .HasMaxLength(500) .HasColumnType("TEXT"); b.Property("Eligibility") .IsRequired() - .HasMaxLength(256) + .HasMaxLength(200) .HasColumnType("TEXT"); - b.Property("EventFormat") - .HasColumnType("INTEGER"); + b.Property("EventFormat") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); b.Property("LevelOfEffort") .HasColumnType("INTEGER"); @@ -69,21 +71,24 @@ namespace Data.Migrations .HasColumnType("INTEGER"); b.Property("SemifinalistActivity") - .HasMaxLength(100) + .HasMaxLength(500) .HasColumnType("TEXT"); b.Property("ShortName") .IsRequired() - .HasMaxLength(40) + .HasMaxLength(50) .HasColumnType("TEXT"); b.Property("Theme") - .HasMaxLength(4096) + .HasMaxLength(500) .HasColumnType("TEXT"); b.HasKey("Id"); - b.HasIndex("Name"); + b.HasIndex("EventFormat"); + + b.HasIndex("Name") + .IsUnique(); b.ToTable("Events"); }); @@ -95,11 +100,12 @@ namespace Data.Migrations .HasColumnType("INTEGER"); b.Property("Email") + .HasMaxLength(255) .HasColumnType("TEXT"); b.Property("FirstName") .IsRequired() - .HasMaxLength(50) + .HasMaxLength(100) .HasColumnType("TEXT"); b.Property("Grade") @@ -107,22 +113,27 @@ namespace Data.Migrations b.Property("LastName") .IsRequired() - .HasMaxLength(50) + .HasMaxLength(100) .HasColumnType("TEXT"); b.Property("NationalId") + .HasMaxLength(50) .HasColumnType("TEXT"); - b.Property("OfficerRole") - .HasColumnType("INTEGER"); + b.Property("OfficerRole") + .HasMaxLength(50) + .HasColumnType("TEXT"); b.Property("PhoneNumber") + .HasMaxLength(20) .HasColumnType("TEXT"); b.Property("RegionalId") + .HasMaxLength(50) .HasColumnType("TEXT"); b.Property("StateId") + .HasMaxLength(50) .HasColumnType("TEXT"); b.Property("TsaYear") @@ -130,21 +141,31 @@ namespace Data.Migrations b.HasKey("Id"); + b.HasIndex("Email"); + + b.HasIndex("Grade"); + + b.HasIndex("FirstName", "LastName"); + b.ToTable("Students"); }); modelBuilder.Entity("Core.Entities.StudentEventRanking", b => { - b.Property("EventDefinitionId") + b.Property("StudentId") .HasColumnType("INTEGER"); - b.Property("StudentId") + b.Property("EventDefinitionId") .HasColumnType("INTEGER"); b.Property("Rank") .HasColumnType("INTEGER"); - b.HasKey("EventDefinitionId", "StudentId"); + b.HasKey("StudentId", "EventDefinitionId"); + + b.HasIndex("EventDefinitionId"); + + b.HasIndex("Rank"); b.HasIndex("StudentId"); @@ -164,7 +185,7 @@ namespace Data.Migrations .HasColumnType("INTEGER"); b.Property("Identifier") - .HasMaxLength(32) + .HasMaxLength(50) .HasColumnType("TEXT"); b.HasKey("Id"); @@ -173,6 +194,8 @@ namespace Data.Migrations b.HasIndex("EventId"); + b.HasIndex("EventId", "Identifier"); + b.ToTable("Teams"); }); @@ -188,7 +211,7 @@ namespace Data.Migrations b.HasIndex("TeamsId"); - b.ToTable("StudentTeam"); + b.ToTable("TeamStudents", (string)null); }); modelBuilder.Entity("Core.Entities.StudentEventRanking", b => @@ -214,12 +237,13 @@ namespace Data.Migrations { b.HasOne("Core.Entities.Student", "Captain") .WithMany() - .HasForeignKey("CaptainId"); + .HasForeignKey("CaptainId") + .OnDelete(DeleteBehavior.SetNull); b.HasOne("Core.Entities.EventDefinition", "Event") .WithMany() .HasForeignKey("EventId") - .OnDelete(DeleteBehavior.Cascade) + .OnDelete(DeleteBehavior.Restrict) .IsRequired(); b.Navigation("Captain");