diff --git a/BlazorApp1/Components/Pages/Management.razor b/BlazorApp1/Components/Pages/Management.razor index 27d8c0b..68f2793 100644 --- a/BlazorApp1/Components/Pages/Management.razor +++ b/BlazorApp1/Components/Pages/Management.razor @@ -322,21 +322,20 @@ else private async Task HandleAddRoleAsync() { - var addedRoleId = _newRole.Id; - await ScheduleService.AddRoleAsync(_newRole); + var addedRole = await ScheduleService.AddRoleAsync(_newRole); await LoadDataAsync(); _newRole = new Role(); - _newPerson.RoleId = addedRoleId; + _newPerson.RoleId = addedRole.Id; _message = "Role byla přidána."; } private async Task HandleAddPersonAsync() { - await ScheduleService.AddPersonAsync(_newPerson); + var createdPerson = await ScheduleService.AddPersonAsync(_newPerson); await LoadDataAsync(); if (_newPerson.Affiliation == "Akademický pracovník") { - _newLesson.LecturerId = _newPerson.Id; + _newLesson.LecturerId = createdPerson.Id; } _newPerson = new Person(); ResetPersonDefaults(); @@ -345,11 +344,10 @@ else private async Task HandleAddLessonTypeAsync() { - var addedTypeId = _newLessonType.Id; - await ScheduleService.AddLessonTypeAsync(_newLessonType); + var addedLessonType = await ScheduleService.AddLessonTypeAsync(_newLessonType); await LoadDataAsync(); _newLessonType = new LessonType(); - _newLesson.LessonTypeId = addedTypeId; + _newLesson.LessonTypeId = addedLessonType.Id; _message = "Druh lekce byl přidán."; } @@ -373,7 +371,7 @@ else } } - private void ToggleStudent(Guid studentId, object? value) + private void ToggleStudent(int studentId, object? value) { var isChecked = value switch { @@ -420,12 +418,12 @@ else _newLesson.ClassroomCode = _classrooms.First().Code; } - if (_newLesson.LessonTypeId == Guid.Empty && _lessonTypes.Any()) + if (_newLesson.LessonTypeId == 0 && _lessonTypes.Any()) { _newLesson.LessonTypeId = _lessonTypes.First().Id; } - if (_newLesson.LecturerId == Guid.Empty) + if (_newLesson.LecturerId == 0) { var lecturer = _people.FirstOrDefault(p => p.Affiliation == "Akademický pracovník"); if (lecturer is not null) diff --git a/BlazorApp1/Components/Pages/Schedule.razor b/BlazorApp1/Components/Pages/Schedule.razor index a6eadb7..e547265 100644 --- a/BlazorApp1/Components/Pages/Schedule.razor +++ b/BlazorApp1/Components/Pages/Schedule.razor @@ -41,8 +41,8 @@ private IEnumerable> _groupedLessons = Enumerable.Empty>(); private Dictionary _subjects = new(); private Dictionary _classrooms = new(); - private Dictionary _lessonTypes = new(); - private Dictionary _people = new(); + private Dictionary _lessonTypes = new(); + private Dictionary _people = new(); protected override async Task OnInitializedAsync() { diff --git a/BlazorApp1/Components/Pages/SubjectDetails.razor b/BlazorApp1/Components/Pages/SubjectDetails.razor index 6c34e32..08d9ce0 100644 --- a/BlazorApp1/Components/Pages/SubjectDetails.razor +++ b/BlazorApp1/Components/Pages/SubjectDetails.razor @@ -61,8 +61,8 @@ else private List _lessons = new(); private List _students = new(); private Dictionary _classrooms = new(); - private Dictionary _lessonTypes = new(); - private Dictionary _people = new(); + private Dictionary _lessonTypes = new(); + private Dictionary _people = new(); protected override async Task OnParametersSetAsync() { diff --git a/BlazorApp1/Data/ScheduleDbContext.cs b/BlazorApp1/Data/ScheduleDbContext.cs index 979b2c6..b232e53 100644 --- a/BlazorApp1/Data/ScheduleDbContext.cs +++ b/BlazorApp1/Data/ScheduleDbContext.cs @@ -24,18 +24,29 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity().Property(d => d.Code).IsRequired(); modelBuilder.Entity().Property(d => d.Name).IsRequired(); + modelBuilder.Entity().Property(c => c.Id).ValueGeneratedOnAdd(); modelBuilder.Entity().Property(c => c.Name).IsRequired(); modelBuilder.Entity().Property(c => c.Code).IsRequired(); + modelBuilder.Entity().Property(s => s.Id).ValueGeneratedOnAdd(); modelBuilder.Entity().Property(s => s.Name).IsRequired(); modelBuilder.Entity().Property(s => s.SubjectCode).IsRequired(); modelBuilder.Entity().Property(s => s.DepartmentCode).IsRequired(); + modelBuilder.Entity().HasIndex(s => s.SubjectCode).IsUnique(); + + modelBuilder.Entity().Property(l => l.Id).ValueGeneratedOnAdd(); modelBuilder.Entity().Property(l => l.Name).IsRequired(); + + modelBuilder.Entity().Property(r => r.Id).ValueGeneratedOnAdd(); modelBuilder.Entity().Property(r => r.RoleType).IsRequired(); + + modelBuilder.Entity().Property(p => p.Id).ValueGeneratedOnAdd(); modelBuilder.Entity().Property(p => p.FirstName).IsRequired(); modelBuilder.Entity().Property(p => p.LastName).IsRequired(); modelBuilder.Entity().Property(p => p.Affiliation).IsRequired(); + modelBuilder.Entity().Property(l => l.Id).ValueGeneratedOnAdd(); + modelBuilder.Entity() .HasKey(ls => new { ls.LessonId, ls.PersonId }); diff --git a/BlazorApp1/Models/Classroom.cs b/BlazorApp1/Models/Classroom.cs index 1fcbb83..4169b5a 100644 --- a/BlazorApp1/Models/Classroom.cs +++ b/BlazorApp1/Models/Classroom.cs @@ -4,7 +4,7 @@ namespace BlazorApp1.Models; public class Classroom { - public Guid Id { get; set; } = Guid.NewGuid(); + public int Id { get; set; } [Required] public string Name { get; set; } = string.Empty; diff --git a/BlazorApp1/Models/Department.cs b/BlazorApp1/Models/Department.cs index 4d81f5a..06ac45c 100644 --- a/BlazorApp1/Models/Department.cs +++ b/BlazorApp1/Models/Department.cs @@ -4,7 +4,7 @@ namespace BlazorApp1.Models; public class Department { - public Guid Id { get; set; } = Guid.NewGuid(); + public int Id { get; set; } [Required] [StringLength(3, MinimumLength = 3)] diff --git a/BlazorApp1/Models/Lesson.cs b/BlazorApp1/Models/Lesson.cs index e6b75f4..8e81ac2 100644 --- a/BlazorApp1/Models/Lesson.cs +++ b/BlazorApp1/Models/Lesson.cs @@ -5,7 +5,7 @@ namespace BlazorApp1.Models; public class Lesson { - public Guid Id { get; set; } = Guid.NewGuid(); + public int Id { get; set; } [Required] public DayOfWeek Day { get; set; } @@ -21,11 +21,11 @@ public class Lesson public string SubjectCode { get; set; } = string.Empty; [Required] - public Guid LessonTypeId { get; set; } + public int LessonTypeId { get; set; } [Required] - public Guid LecturerId { get; set; } + public int LecturerId { get; set; } [NotMapped] - public List StudentIds { get; set; } = new(); + public List StudentIds { get; set; } = new(); } diff --git a/BlazorApp1/Models/LessonStudent.cs b/BlazorApp1/Models/LessonStudent.cs index 43bee44..afa5214 100644 --- a/BlazorApp1/Models/LessonStudent.cs +++ b/BlazorApp1/Models/LessonStudent.cs @@ -2,7 +2,7 @@ namespace BlazorApp1.Models; public class LessonStudent { - public Guid LessonId { get; set; } + public int LessonId { get; set; } - public Guid PersonId { get; set; } + public int PersonId { get; set; } } diff --git a/BlazorApp1/Models/LessonType.cs b/BlazorApp1/Models/LessonType.cs index b2d663d..fe94e0a 100644 --- a/BlazorApp1/Models/LessonType.cs +++ b/BlazorApp1/Models/LessonType.cs @@ -4,7 +4,7 @@ namespace BlazorApp1.Models; public class LessonType { - public Guid Id { get; set; } = Guid.NewGuid(); + public int Id { get; set; } [Required] public string Name { get; set; } = string.Empty; diff --git a/BlazorApp1/Models/Person.cs b/BlazorApp1/Models/Person.cs index 063ac1f..d8609d6 100644 --- a/BlazorApp1/Models/Person.cs +++ b/BlazorApp1/Models/Person.cs @@ -4,7 +4,7 @@ namespace BlazorApp1.Models; public class Person { - public Guid Id { get; set; } = Guid.NewGuid(); + public int Id { get; set; } [Required] public string FirstName { get; set; } = string.Empty; @@ -17,7 +17,7 @@ public class Person [Required] public string Affiliation { get; set; } = string.Empty; - public Guid? RoleId { get; set; } + public int? RoleId { get; set; } public string FullName => string.IsNullOrWhiteSpace(Title) ? $"{FirstName} {LastName}" diff --git a/BlazorApp1/Models/Role.cs b/BlazorApp1/Models/Role.cs index 0f0eee2..db0e919 100644 --- a/BlazorApp1/Models/Role.cs +++ b/BlazorApp1/Models/Role.cs @@ -4,7 +4,7 @@ namespace BlazorApp1.Models; public class Role { - public Guid Id { get; set; } = Guid.NewGuid(); + public int Id { get; set; } [Required] public string RoleType { get; set; } = string.Empty; diff --git a/BlazorApp1/Models/Subject.cs b/BlazorApp1/Models/Subject.cs index e23d6ab..28585c0 100644 --- a/BlazorApp1/Models/Subject.cs +++ b/BlazorApp1/Models/Subject.cs @@ -4,7 +4,7 @@ namespace BlazorApp1.Models; public class Subject { - public Guid Id { get; set; } = Guid.NewGuid(); + public int Id { get; set; } [Required] public string Name { get; set; } = string.Empty; diff --git a/BlazorApp1/Services/ScheduleService.cs b/BlazorApp1/Services/ScheduleService.cs index 74a2622..2120ff0 100644 --- a/BlazorApp1/Services/ScheduleService.cs +++ b/BlazorApp1/Services/ScheduleService.cs @@ -1,6 +1,7 @@ using BlazorApp1.Data; using BlazorApp1.Models; using Microsoft.EntityFrameworkCore; +using System.Data.Common; namespace BlazorApp1.Services; @@ -16,7 +17,13 @@ public ScheduleService(IDbContextFactory dbFactory) public async Task InitializeAsync() { await using var db = await _dbFactory.CreateDbContextAsync(); - await db.Database.EnsureCreatedAsync(); + var created = await db.Database.EnsureCreatedAsync(); + + if (!created && !await HasExpectedColumnsAsync(db)) + { + await db.Database.EnsureDeletedAsync(); + await db.Database.EnsureCreatedAsync(); + } if (!await db.Departments.AnyAsync()) { @@ -95,67 +102,75 @@ public async Task> GetLessonsAsync() return await db.Classrooms.AsNoTracking().FirstOrDefaultAsync(c => c.Code == code); } - public async Task GetLessonTypeAsync(Guid id) + public async Task GetLessonTypeAsync(int id) { await using var db = await _dbFactory.CreateDbContextAsync(); return await db.LessonTypes.AsNoTracking().FirstOrDefaultAsync(l => l.Id == id); } - public async Task GetPersonAsync(Guid id) + public async Task GetPersonAsync(int id) { await using var db = await _dbFactory.CreateDbContextAsync(); return await db.People.AsNoTracking().FirstOrDefaultAsync(p => p.Id == id); } - public async Task AddClassroomAsync(Classroom classroom) + public async Task AddClassroomAsync(Classroom classroom) { await using var db = await _dbFactory.CreateDbContextAsync(); db.Classrooms.Add(classroom); await db.SaveChangesAsync(); + return classroom; } - public async Task AddDepartmentAsync(Department department) + public async Task AddDepartmentAsync(Department department) { await using var db = await _dbFactory.CreateDbContextAsync(); db.Departments.Add(department); await db.SaveChangesAsync(); + return department; } - public async Task AddSubjectAsync(Subject subject) + public async Task AddSubjectAsync(Subject subject) { await using var db = await _dbFactory.CreateDbContextAsync(); db.Subjects.Add(subject); await db.SaveChangesAsync(); + return subject; } - public async Task AddRoleAsync(Role role) + public async Task AddRoleAsync(Role role) { await using var db = await _dbFactory.CreateDbContextAsync(); db.Roles.Add(role); await db.SaveChangesAsync(); + return role; } - public async Task AddPersonAsync(Person person) + public async Task AddPersonAsync(Person person) { await using var db = await _dbFactory.CreateDbContextAsync(); db.People.Add(person); await db.SaveChangesAsync(); + return person; } - public async Task AddLessonTypeAsync(LessonType lessonType) + public async Task AddLessonTypeAsync(LessonType lessonType) { await using var db = await _dbFactory.CreateDbContextAsync(); db.LessonTypes.Add(lessonType); await db.SaveChangesAsync(); + return lessonType; } - public async Task AddLessonAsync(Lesson lesson) + public async Task AddLessonAsync(Lesson lesson) { await using var db = await _dbFactory.CreateDbContextAsync(); var studentIds = lesson.StudentIds.ToList(); - lesson.StudentIds = new List(); + lesson.StudentIds = new List(); db.Lessons.Add(lesson); + await db.SaveChangesAsync(); + if (studentIds.Any()) { db.LessonStudents.AddRange(studentIds.Select(s => new LessonStudent @@ -163,9 +178,10 @@ public async Task AddLessonAsync(Lesson lesson) LessonId = lesson.Id, PersonId = s })); + await db.SaveChangesAsync(); } - await db.SaveChangesAsync(); + return lesson; } private static async Task SeedAsync(ScheduleDbContext db) @@ -176,6 +192,7 @@ private static async Task SeedAsync(ScheduleDbContext db) new() { Code = "KIT", Name = "Katedra informačních technologií" } }; db.Departments.AddRange(departments); + await db.SaveChangesAsync(); var roles = new List { @@ -184,6 +201,7 @@ private static async Task SeedAsync(ScheduleDbContext db) new() { RoleType = "Garant" } }; db.Roles.AddRange(roles); + await db.SaveChangesAsync(); var people = new List { @@ -209,6 +227,7 @@ private static async Task SeedAsync(ScheduleDbContext db) } }; db.People.AddRange(people); + await db.SaveChangesAsync(); var classrooms = new List { @@ -216,6 +235,7 @@ private static async Task SeedAsync(ScheduleDbContext db) new() { Name = "Počítačová laboratoř", Code = "PC204", Floor = 2, Capacity = 32, Purpose = "Počítačová" } }; db.Classrooms.AddRange(classrooms); + await db.SaveChangesAsync(); var lessonTypes = new List { @@ -224,6 +244,7 @@ private static async Task SeedAsync(ScheduleDbContext db) new() { Name = "Seminář" } }; db.LessonTypes.AddRange(lessonTypes); + await db.SaveChangesAsync(); var subjects = new List { @@ -243,6 +264,7 @@ private static async Task SeedAsync(ScheduleDbContext db) } }; db.Subjects.AddRange(subjects); + await db.SaveChangesAsync(); var lecturer = people.First(p => p.Affiliation == "Akademický pracovník"); var studentIds = people.Where(p => p.Affiliation == "Student").Select(p => p.Id).ToList(); @@ -284,6 +306,7 @@ private static async Task SeedAsync(ScheduleDbContext db) } }; db.Lessons.AddRange(lessons); + await db.SaveChangesAsync(); db.LessonStudents.AddRange(lessons.SelectMany(l => studentIds.Select(s => new LessonStudent { @@ -293,4 +316,32 @@ private static async Task SeedAsync(ScheduleDbContext db) await db.SaveChangesAsync(); } + + private static async Task HasExpectedColumnsAsync(ScheduleDbContext db) + { + var connection = db.Database.GetDbConnection(); + await connection.OpenAsync(); + await using var command = connection.CreateCommand(); + command.CommandText = "PRAGMA table_info('People');"; + var columns = new Dictionary(StringComparer.OrdinalIgnoreCase); + + await using var reader = await command.ExecuteReaderAsync(); + while (await reader.ReadAsync()) + { + var name = reader.GetString(1); + var type = reader.GetString(2); + columns[name] = type; + } + + await connection.CloseAsync(); + + var expectedColumns = new[] { "Id", "FirstName", "LastName", "Title", "Affiliation", "RoleId" }; + if (expectedColumns.Any(c => !columns.ContainsKey(c))) + { + return false; + } + + return columns.TryGetValue("Id", out var idType) + && idType.Contains("INT", StringComparison.OrdinalIgnoreCase); + } }