Как сохранить изменения в шаблоне проектирования .NET 8 EF Core DDD AggregateRootC#

Место общения программистов C#
Ответить
Anonymous
 Как сохранить изменения в шаблоне проектирования .NET 8 EF Core DDD AggregateRoot

Сообщение Anonymous »

Я работаю над проектом по управлению персоналом и пытаюсь сохранить изменения сущностей с помощью EF Core и .NET 8.
Контроллер:

Код: Выделить всё

[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);
}
}
Обработчик команд CQRS:

Код: Выделить всё

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;
}
}
Метод SaveChanges репозитория (временный метод):

Код: Выделить всё

public async Task SaveChanges(CancellationToken cancellationToken)
{
await _context.SaveChangesAsync(cancellationToken);
}
Теперь у меня есть 2 основных объекта: Сотрудник — корень агрегата и LeaveRequest, который является частью этого агрегата.

Код: Выделить всё

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);
}
}
Я просто не понимаю, почему SaveChanges не работает, я тоже отслеживаю все сущности.

Код: Выделить всё

services.AddDbContext
(
options =>
{
options.UseQueryTrackingBehavior(QueryTrackingBehavior.TrackAll);
options.UseSqlServer
(
configuartion.GetConnectionString("DefaultConnection")
);
}
);
Я не пробовал много вещей, но мне также не удалось найти хороший пример для изучения.

Подробнее здесь: https://stackoverflow.com/questions/790 ... gn-pattern
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»