Контроллер:
Код: Выделить всё
[Route("api/[controller]")]
[ApiController]
[Authorize]
public class LeaveController : BaseController
{
private readonly IMediator _mediator;
public LeaveController(IMediator mediator)
{
_mediator = mediator;
}
[HttpPost]
public async Task SubmitLeaveRequest([FromBody] SubmitLeaveRequest submitLeaveRequest)
{
var command = new SubmitLeaveRequestCommand(GetCurrentUserId(), submitLeaveRequest.StartDate, submitLeaveRequest.EndDate, submitLeaveRequest.Reason);
var data = await _mediator.Send(command);
return CreateResponse(data);
}
}
Код: Выделить всё
public class SubmitLeaveRequestCommandHandler : IRequestHandler
{
private readonly IEmployeeRepository _repository;
public SubmitLeaveRequestCommandHandler(IEmployeeRepository repository)
{
_repository = repository;
}
public async Task Handle(SubmitLeaveRequestCommand request, CancellationToken cancellationToken)
{
var employee = await _repository.GetEmployeeByUserIdAsync(request.UserId);
if (employee == null)
throw new Exception("Not Found");
employee.AddLeaveRequest(request.StartDate, request.EndDate, request.Reason);
await _repository.SaveChanges(cancellationToken);
return Unit.Value;
}
}
Код: Выделить всё
public async Task SaveChanges(CancellationToken cancellationToken)
{
await _context.SaveChangesAsync(cancellationToken);
}
Код: Выделить всё
public class Employee : AggregateRoot
{
public string UserId { get; private set; }
public string FirstName { get; set; }
public string LastName { get; private set; }
public string Position { get; private set; }
public Address Address { get; private set; }
private readonly List _leaveRequests = new List();
public IReadOnlyCollection LeaveRequests => _leaveRequests.AsReadOnly();
public Employee() {}
public Employee(string userId, string firstName, string lastName, string position, Address address)
{
Id = Guid.NewGuid();
UserId = userId;
FirstName = firstName;
LastName = lastName;
Position = position;
Address = address;
AddDomainEvent(new EmployeeCreatedEvent(this));
}
public void AddLeaveRequest(DateTime startDate, DateTime endDate, string reason)
{
var leaveRequest = new LeaveRequest(startDate, endDate, reason, Id);
_leaveRequests.Add(leaveRequest);
AddDomainEvent(new LeaveRequestAddedEvent(leaveRequest));
}
}
public class LeaveRequest : Entity
{
public DateTime StartDate { get; private set; }
public DateTime EndDate { get; private set; }
public string Reason { get; private set; }
public bool IsApproved { get; private set; }
public string? RejectionReason { get; private set; }
public Guid EmployeeId { get; set; }
public LeaveRequest() {}
public LeaveRequest(DateTime startDate, DateTime endDate, string reason, Guid employeeId)
{
Id = Guid.NewGuid();
StartDate = startDate;
EndDate = endDate;
Reason = reason;
IsApproved = false;
EmployeeId = employeeId;
}
public void Approve()
{
IsApproved = true;
}
public void Reject(string rejectionReason)
{
IsApproved = false;
RejectionReason = rejectionReason;
}
}
Microsoft .EntityFrameworkCore.DbUpdateConcurrencyException: ожидалось, что операция базы данных повлияет на 1 строку (строки), но фактически затронула 0 строк; данные могли быть изменены или удалены с момента загрузки объектов. См. https://go.microsoft.com/fwlink/?LinkId=527962 для получения информации о понимании и обработке исключений оптимистического параллелизма.
База данных выглядит нормально. , необходимые отношения имеются, простые для многих.
Это мой контекст:
Код: Выделить всё
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions options) : base(options) { }
public DbSet Employees { get; set; }
public DbSet LeaveRequests { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Ignore();
modelBuilder.Entity()
.OwnsOne(e => e.Address, a =>
{
a.Property(ad => ad.Street).HasColumnName("Street").IsRequired();
a.Property(ad => ad.City).HasColumnName("City").IsRequired();
a.Property(ad => ad.State).HasColumnName("State").IsRequired();
a.Property(ad => ad.ZipCode).HasColumnName("ZipCode").IsRequired();
});
modelBuilder.Entity()
.HasMany(e => e.LeaveRequests);
modelBuilder.Entity()
.HasIndex(e => e.UserId)
.IsUnique();
base.OnModelCreating(modelBuilder);
}
}
Код: Выделить всё
services.AddDbContext
(
options =>
{
options.UseQueryTrackingBehavior(QueryTrackingBehavior.TrackAll);
options.UseSqlServer
(
configuartion.GetConnectionString("DefaultConnection")
);
}
);
Подробнее здесь: https://stackoverflow.com/questions/790 ... gn-pattern
Мобильная версия