namespace Adapters.Driven.Persistence.Repositories; using Adapters.Driven.Persistence.Context; using Domain.Entities; using Domain.Ports.Repositories; using Domain.ReadModels; using Microsoft.EntityFrameworkCore; /// /// EF Core implementation of . /// public class EnrollmentRepository(AppDbContext context) : IEnrollmentRepository { public async Task GetByIdAsync(int id, CancellationToken ct = default) => await context.Enrollments.FindAsync([id], ct); public async Task GetByStudentAndSubjectAsync(int studentId, int subjectId, CancellationToken ct = default) => await context.Enrollments .FirstOrDefaultAsync(e => e.StudentId == studentId && e.SubjectId == subjectId, ct); public async Task> GetByStudentIdAsync(int studentId, CancellationToken ct = default) => await context.Enrollments .Include(e => e.Subject) .ThenInclude(s => s.Professor) .Where(e => e.StudentId == studentId) .AsNoTracking() .ToListAsync(ct); public async Task> GetBySubjectIdAsync(int subjectId, CancellationToken ct = default) => await context.Enrollments .Include(e => e.Student) .Where(e => e.SubjectId == subjectId) .AsNoTracking() .ToListAsync(ct); public async Task> GetClassmatesAsync(int studentId, int subjectId, CancellationToken ct = default) => await context.Enrollments .Where(e => e.SubjectId == subjectId && e.StudentId != studentId) .Select(e => new ClassmateInfo(e.Student.Id, e.Student.Name)) .ToListAsync(ct); public async Task>> GetClassmatesBatchAsync( int studentId, IEnumerable subjectIds, CancellationToken ct = default) { var subjectIdList = subjectIds.ToList(); if (subjectIdList.Count == 0) return new Dictionary>(); // Single query to get all classmates for all subjects - projects directly to ClassmateInfo // Note: AsNoTracking is not needed for projections (Select) as they're not tracked by default var enrollments = await context.Enrollments .Where(e => subjectIdList.Contains(e.SubjectId) && e.StudentId != studentId) .Select(e => new { e.SubjectId, Classmate = new ClassmateInfo(e.Student.Id, e.Student.Name) }) .ToListAsync(ct); // Group by SubjectId return enrollments .GroupBy(e => e.SubjectId) .ToDictionary( g => g.Key, g => (IReadOnlyList)g.Select(e => e.Classmate).ToList()); } public void Add(Enrollment enrollment) => context.Enrollments.Add(enrollment); public void Delete(Enrollment enrollment) => context.Enrollments.Remove(enrollment); }