How to mutate a one-to-many relationship using EF Core and Dto's?
I'm trying to edit a list of trainees by adding / removing a user using DTO's and EF-core. So far adding a user to the list persists but not the removal. What am I missing?
Thank you so much for the help!
This is the code:
Domain:
public class Session : Entity
{
#region FIELDS
private string title;
private string description;
private DateTime startsAt;
private DateTime endsAt;
private List<User> trainees = new();
#endregion
#region PROPERTIES
public User Coach { get; set; }
public DateTime? UpdatedOn { get; set; }
public DateTime? CreatedOn { get; set; }
public Workout Workout { get; set; }
public DateTime StartsAt
{
get { return startsAt; }
set { startsAt = Guard.Against.Null(value, nameof(startsAt)); }
}
public DateTime EndsAt
{
get { return endsAt; }
set { endsAt = Guard.Against.Null(value, nameof(endsAt)); }
}
public string Title
{
get { return title; }
set { title = Guard.Against.NullOrWhiteSpace(value, nameof(title)); }
}
public string Description
{
get { return description; }
set { description = Guard.Against.NullOrWhiteSpace(value, nameof(description)); }
}
public IReadOnlyCollection<User> Trainees => trainees.AsReadOnly();
#endregion
#region CONSTRUCTORS
private Session() { }
public Session(string title, string description, DateTime startsAt, DateTime endsAt, User coach,Workout workout)
{
Title = title;
Description = description;
StartsAt = startsAt;
EndsAt = endsAt;
Coach = Guard.Against.Null(coach);
Workout = Guard.Against.Null(workout);
}
#endregion
#region METHODS
public void AddReservation(User user)
{
if (trainees.Count >= 6) throw new ArgumentException("Session is fully booked");
trainees.Add(user);
user.AddUserWorkout(Workout);
}
public void RemoveReservation(User user)
{
trainees.Remove(user);
user.RemoveUserWorkout(Workout);
}
#endregion
}
DTO's:
public static class SessionDto
{
public class Index
{
public int Id { get; set; }
public string Title { get; set; }
public DateTime StartsAt { get; set; }
public DateTime EndsAt { get; set; }
public string Description { get; set; }
public WorkoutDto.Index Workout { get; set; }
public UserDto.Index Coach { get; set; }
}
public class Detail : Index
{
public List<UserDto.Index>? Trainees { get; set; }
}
public class MutateTrainees
{
public int TraineeId { get; set; }
public class Validator : AbstractValidator<Mutate>
{
public Validator()
{
}
}
}
}
Services:
public async Task<SessionResponse.MutateTrainee> AddTrainee(SessionRequest.MutateTrainee request)
{
SessionResponse.MutateTrainee res = new();
var session = await GetSessionById(request.SessionId).SingleOrDefaultAsync();
var user = await GetUserById(request.MutateTrainees.TraineeId).SingleOrDefaultAsync();
Guard.Against.Null(session, nameof(session));
Guard.Against.Null(user, nameof(user));
session.AddReservation(user);
DbCtx.Entry(user).State = EntityState.Modified;
DbCtx.Entry(session).State = EntityState.Modified;
await DbCtx.SaveChangesAsync();
res.SessionId = session.Id;
return res;
}
public async Task<SessionResponse.MutateTrainee> RemoveTrainee(SessionRequest.MutateTrainee request)
{
SessionResponse.MutateTrainee res = new();
var session = await GetSessionById(request.SessionId).SingleOrDefaultAsync();
var user = await GetUserById(request.MutateTrainees.TraineeId).SingleOrDefaultAsync();
Guard.Against.Null(session, nameof(session));
Guard.Against.Null(user, nameof(user));
session.RemoveReservation(user);
DbCtx.Entry(session).State = EntityState.Modified;
DbCtx.Entry(user).State = EntityState.Modified;
await DbCtx.SaveChangesAsync();
res.SessionId = session.Id;
return res;
}