Asp.Net
April 10, 2019

Проект "Отпуск сотрудников". Часть 2, хранилище и контроллер.


!!НАШ БЛОГ ПЕРЕЕХАЛ!!

Мы создали свой сайт! Все материалы, опубликованные в этом блоге, переехали туда.

Наш новый сайт maddevelop.ru


Создадим интерфейс IEmployeeRepository, в котором будут свойства с названиями таблиц из базы данных, а также методы для добавления и удаления элементов в таблицы.

public interface IEmployeeRepository
{
    IEnumerable<Employee> Employees { get; }
    IEnumerable<Vacation> Vacations { get; }
    IEnumerable<Color> Colors { get; }

    Employee AddEmployee(Employee employee);
    void DeleteEmployee(int id);

    void AddVacation(int employeeId, Vacation vacation);
    void DeleteVacation(int employeeId, int vacationId);
}

Определим класс EFEmployeeRepository, реализующий интерфейс IEmployeeRepository.

public class EFEmployeeRepository : IEmployeeRepository
{
    private ApplicationDbContext context;

    public EFEmployeeRepository(ApplicationDbContext ctx)
    {
        context = ctx;
    }

    public IEnumerable<Color> Colors => context.Colors;
    public IEnumerable<Employee> Employees => context.Employees.Include(v => v.Vacations);
    public IEnumerable<Vacation> Vacations => context.Vacations; 

    .....
}

Так как между таблицами базы данных Employees и Vacations имеется связь "один-ко-многим", то вместе со списком сотрудников требуется подгружать список отпусков, используя метод Include().

public IEnumerable<Employee> Employees => context.Employees.Include(v => v.Vacations);

Нам не требуется смотреть список сотрудников, цвета которых в сводной таблице окрашиваются одним цветом, поэтому просто получаем список цветов, без Include().

public IEnumerable<Color> Colors => context.Colors;

Методы добавления и удаления сущностей опишем так:

public Employee AddEmployee(Employee employee)
{
    context.Employees.Add(employee);
    context.SaveChanges();
    return employee;
}

public void DeleteEmployee(int id)
{
    Employee deletedEmployee = context.Employees.FirstOrDefault(e => e.EmployeeId == id);
    if (deletedEmployee != null)
    {
        context.Employees.Remove(deletedEmployee);
        context.SaveChanges();
    }
}

public void AddVacation(int employeeId, Vacation vacation)
{
    Employee changedEmployee = context.Employees
        .FirstOrDefault(e => e.EmployeeId == employeeId);
    if (changedEmployee != null)
    {
        changedEmployee.Vacations.Add(vacation);
        context.SaveChanges();
    }            
}

public void DeleteVacation(int employeeId, int vacationId)
{
    Employee changedEmployee = context.Employees
        .FirstOrDefault(e => e.EmployeeId == employeeId);
    if (changedEmployee != null)
    {
        Vacation deletedVacation = changedEmployee.Vacations
            .FirstOrDefault(v => v.VacationId == vacationId);
        if (deletedVacation != null)
        {
            changedEmployee.Vacations.Remove(deletedVacation);
            context.SaveChanges();
        }
    }           
}

Теперь реализуем API-контроллер.

[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
    private IEmployeeRepository employeeRepository;

    public ValuesController(IEmployeeRepository repo)
    {
        employeeRepository = repo;
    }        

    public IEnumerable<Employee> GetEmployees()
    {
        return employeeRepository.Employees;
    }

    [HttpGet("colors")]
    public IEnumerable<Color> GetColors()
    {
        return employeeRepository.Colors;
    }

    [HttpPost]
    public Employee PostEmployee([FromBody]Employee employee)
    {
        return employeeRepository.AddEmployee(employee);
    }

    [HttpDelete("{id}")]
    public void DeleteEmployee(int id)
    {
        employeeRepository.DeleteEmployee(id);
    }

    [HttpPost("vacation")]
    public void AddVacation([FromBody]VacationViewModel vacationVM)
    {
        employeeRepository.AddVacation(vacationVM.EmployeeId, vacationVM.Vacation);
    }

    [HttpDelete("{idE}/{idV}")]
    public void DeleteVacation(int idE, int idV)
    {
        employeeRepository.DeleteVacation(idE, idV);
    }
}

Для пояснения работы контроллера приведём таблицу, в которой для каждого маршрута приведён метод запроса и метод, который этим запросом вызывается.

Стоит отметить, что для добавления нового отпуска у сотрудника требуется передавать в контроллер идентификатор сотрудника и класс нового отпуска. Для передачи двух объектов используется вспомогательный класс.

public class VacationViewModel
{
    public int EmployeeId { get; set; }
    public Vacation Vacation { get; set; }
}

На этом разработка серверной части закончена. В следующих частях будет описан интерфейс пользователя.


Ещё больше интересной информации на нашем Telegram-канале.

<< К части 1 << ......... >> К части 3 >>