using Microsoft.EntityFrameworkCore; using Nashel.Modules.Identity.Domain.Aggregates; using Nashel.Modules.Identity.Domain.Entities; using Nashel.Modules.Identity.Domain.Repositories; using Nashel.Modules.Identity.Infrastructure.Persistence; namespace Nashel.Modules.Identity.Infrastructure.Repositories; public class AccountRepository : IAccountRepository { private readonly IdentityDbContext _context; public AccountRepository(IdentityDbContext context) { _context = context; } public async Task AddAsync(Account account, CancellationToken cancellationToken) { // Явно добавляем профиль, чтобы EF Core сохранил его в таблицу UserProfiles if (account.Profile != null) { await _context.UserProfiles.AddAsync(account.Profile, cancellationToken); // Добавляем WorkSchedule если есть if (account.Profile.WorkSchedule != null) { await _context.WorkSchedules.AddAsync(account.Profile.WorkSchedule, cancellationToken); } } await _context.Accounts.AddAsync(account, cancellationToken); await _context.SaveChangesAsync(cancellationToken); } public async Task GetByIdAsync(Guid id, CancellationToken cancellationToken) { return await _context.Accounts .Include(a => a.Profile) .ThenInclude(p => p.Competencies) .Include(a => a.Profile) .ThenInclude(p => p.WorkSchedule) .FirstOrDefaultAsync(a => a.Id == id, cancellationToken); } public async Task> GetByIdsAsync(IEnumerable ids, CancellationToken cancellationToken) { return await _context.Accounts .Include(a => a.Profile) .Where(a => ids.Contains(a.Id)) .ToListAsync(cancellationToken); } public async Task GetByPhoneAsync(string phone, CancellationToken cancellationToken) { return await _context.Accounts .Include(a => a.Profile) .FirstOrDefaultAsync(a => a.Phone == phone, cancellationToken); } public async Task GetByPhoneIncludingDeletedAsync(string phone, CancellationToken cancellationToken) { return await _context.Accounts .IgnoreQueryFilters() .Include(a => a.Profile) .FirstOrDefaultAsync(a => a.Phone == phone, cancellationToken); } public async Task UpdateAsync(Account account, CancellationToken cancellationToken) { Console.WriteLine($"[AccountRepository.UpdateAsync] Starting update for account: {account.Id}"); // Явно обновляем профиль, чтобы EF Core сохранил изменения в таблицу UserProfiles if (account.Profile != null) { Console.WriteLine($"[AccountRepository.UpdateAsync] Profile found: {account.Profile.Id}"); // Загружаем текущий профиль с компетенциями var existingProfile = await _context.UserProfiles .Include(p => p.Competencies) .Include(p => p.WorkSchedule) .FirstOrDefaultAsync(p => p.Id == account.Profile.Id, cancellationToken); if (existingProfile != null) { Console.WriteLine($"[AccountRepository.UpdateAsync] Existing profile loaded"); // Обновляем свойства профиля existingProfile.Update( account.Profile.FirstName, account.Profile.LastName, account.Profile.Patronymic, account.Profile.CompanyName, account.Profile.Inn, account.Profile.Description, account.Profile.Location, account.Profile.CurrentLocation ); // Обновляем компетенции через доменный метод // Поскольку компетенции уже сохранены через CompetencyRepository, // просто загружаем их из БД по Id для правильной работы EF Core var competencies = new List(); if (account.Profile.Competencies != null && account.Profile.Competencies.Any()) { var competencyIds = account.Profile.Competencies .Select(c => c.Id) .Distinct() .ToList(); Console.WriteLine($"[AccountRepository.UpdateAsync] Loading {competencyIds.Count} competencies from DB"); competencies = await _context.Competencies .Where(c => competencyIds.Contains(c.Id)) .ToListAsync(cancellationToken); } existingProfile.UpdateCompetencies(competencies); // Обновляем WorkSchedule if (account.Profile.WorkSchedule != null) { if (existingProfile.WorkSchedule != null) { // Обновляем существующий WorkSchedule existingProfile.WorkSchedule.Update( account.Profile.WorkSchedule.IsAlwaysReady, account.Profile.WorkSchedule.WorkingDays ); } else { // Создаём новый WorkSchedule var newSchedule = WorkSchedule.Create( account.Profile.WorkSchedule.IsAlwaysReady, account.Profile.WorkSchedule.WorkingDays ); // EF Core сам установит правильную связь через Id профиля existingProfile.SetWorkSchedule(newSchedule); _context.WorkSchedules.Add(newSchedule); } } _context.UserProfiles.Update(existingProfile); } else { Console.WriteLine($"[AccountRepository.UpdateAsync] Existing profile not found, using account profile"); _context.UserProfiles.Update(account.Profile); } } _context.Accounts.Update(account); Console.WriteLine($"[AccountRepository.UpdateAsync] Saving changes to database"); await _context.SaveChangesAsync(cancellationToken); Console.WriteLine($"[AccountRepository.UpdateAsync] Successfully completed"); } }