public async Task SeedAllAsync(CancellationToken cancellationToken) { if (context.PaidTimeOffPolicies.Any()) { logger.LogInformation("Database has already been initialized with basic data. Nothing to do."); return; } await SeedPtoPoliciesAsync(); await SeedCurrenciesAsync(); await context.SaveChangesAsync(cancellationToken); }
public async Task <RegisterOrUpdateEmployeeCommand> Handle(RegisterOrUpdateEmployeeCommand request, CancellationToken cancellationToken) { // Map the view model to a domain entity. We are now in the realm of business entities and logic. var employee = employeeVmToDomainEntityMapper.MapToDomainEntity(request); var isNewEmployee = employee.Id == null; // Look up manager from DB. EmployeeEntity managerEntity = null; if (request.ManagerId != null) { managerEntity = await context.Employees.FindAsync(request.ManagerId); if (managerEntity == null) { throw new EmployeeException($"Manager with ID {request.ManagerId} not found."); } // Convert to domain entity as well. employee = employee.WithManager(employeeDomainToDbEntityMapper.MapToDomainEntity(managerEntity)); } // Look up subordinates and map those to domain entities. var subordinateIds = request.SubordinateIds.ToArray(); var subordinateEntities = await(from e in context.Employees.AsNoTracking() where subordinateIds.Contains(e.Id) select e).ToArrayAsync(); employee = employee.WithSubordinates(from e in subordinateEntities select employeeDomainToDbEntityMapper.MapToDomainEntity(e)); // Get PTO policy for this employee and map to domain entity. var policyEntity = await context.PaidTimeOffPolicies.AsNoTracking().FirstOrDefaultAsync(p => p.Id == request.PaidTimeOffPolicyId); if (policyEntity == null) { throw new EmployeeException($"PTO policy not found."); } var policy = ptoPolicyDomainToDbEntityMapper.MapToDomainEntity(policyEntity); employee = employee.WithPaidTimeOffPolicy(policy); // Check the validity of the employee's PTO hours and other business logic. All business rule validation is still happening within the Domain layer... employee.AssertAggregates(); employee.VerifyEmployeeManagerAndSubordinates(); if (isNewEmployee) { employee.VerifyStartingPtoHoursAreValid(); } else { employee.VerifyPtoHoursAreValid(); } // End business logic. // Convert back to persistence entity. var employeeEntity = employeeDomainToDbEntityMapper.MapToDbEntity(employee); employeeEntity.TenantId = TenantId; var entry = await context.Employees.AddAsync(employeeEntity); if (!isNewEmployee) { entry.State = EntityState.Modified; } // Delete previous entity relationships. context.EmployeeManagers.RemoveRange(context.EmployeeManagers.Where(em => em.EmployeeId == employee.Id)); context.EmployeeManagers.RemoveRange(context.EmployeeManagers.Where(em => em.ManagerId == employee.Id)); // Commit transaction to DB. await context.SaveChangesAsync(cancellationToken); // Create new relationships. if (employee.Manager != null) { await context.EmployeeManagers.AddAsync(new EmployeeManagerEntity { TenantId = TenantId, EmployeeId = employeeEntity.Id, ManagerId = managerEntity.Id }); } await context.EmployeeManagers.AddRangeAsync(from s in subordinateEntities select new EmployeeManagerEntity { TenantId = TenantId, EmployeeId = s.Id, ManagerId = employeeEntity.Id }); // Commit transaction to DB. if (context.HasChanges) { await context.SaveChangesAsync(cancellationToken); } // Set ID of domain entity. employee.Id = employeeEntity.Id; // Kick off domain events. employee.CreateEmployeeRegisteredEvent(dateTimeService); await employee.DispatchDomainEventsAsync(); // Map from domain entity back to VM (command) and return that. return(employeeVmToDomainEntityMapper.MapToViewModel(employee)); }