0

I have Team and Player tables. A team can have maximum of 6 players. This implemented in business logic. But if concurrent requests occurs teams might ended up with 7 players. What is correct way to avoid this in ef core.

Changing concurrency model only for this feels like overkill.

HasCheckConstraint promising but requires writing raw sql in efcore not feels like idiomatic. Also not sure about correct syntax. This gives

42703: column "Players" does not exist error.

modelBuilder.Entity<Team>()
    .HasCheckConstraint("CK_Team_MaxPlayers", $"COUNT(\"Players\") <= 6");

Another solution implement transaction for every player add. But not sure about correct method.

await using var transaction =
    await context.Database.BeginTransactionAsync();

try
{
    var newPlayer = new TeamPlayer
    {
        UserId = user.Id,
    };
    
    team.Players.Add(newPlayer);
    await transaction.CommitAsync();
    
    //then what? check member count and rollback?
    //can i rollback committed transaction?
}
catch (Exception)
{
    // TODO: Handle failure
}
Ivan Gechev
  • 706
  • 3
  • 9
  • 21
okanace
  • 1
  • 1
  • In my opinion, raw SQL is suitable for this purpose. | See https://stackoverflow.com/q/3880698/5045688 how to do this – Alexander Petrov Jun 15 '23 at 10:59
  • Also, it can be implemented using a trigger. – Alexander Petrov Jun 15 '23 at 11:01
  • If your database supports materialized/indexed views, you can create a view with a unique index enforcing the constraint. See https://spaghettidba.com/2011/08/03/enforcing-complex-constraints-with-indexed-views/ for some examples. – pjs Jun 16 '23 at 10:16

0 Answers0