I am having trouble determining how to implement the following scenario in an ASP.NET Core Web API using Identity and Entity Framework:
- If an AppUser is given the Performer role when it is created, it must be associated with one and only one Performer object.
- Otherwise, if an AppUser has the Venue role when it is created, it must be associated with one and only one Venue object.
- Each Performer and Venue object must be associated with one and only one AppUser, and should not be able to exist otherwise.
I'm making an App for creating Bookings between Performers and Venues, using the models below:
public class Performer{ public int Id { get; set; } public string Name { get; set; } = string.Empty; public string Description { get; set; } = string.Empty; public List<Booking> Bookings { get; set; } = new List<Booking>();}
public class Venue{ public int Id { get; set; } public string Name { get; set; } = string.Empty; public string Address { get; set; } = string.Empty; public List<Booking> Bookings { get; set; } = new List<Booking>();}
public class Booking{ public int Id { get; set; } [Column(TypeName = "decimal(18,2)")] public decimal PaymentAmount { get; set; } public int? PerformerId { get; set; } public Performer? Performer { get; set; } public int? VenueId { get; set; } public Venue? Venue { get; set; } public DateTime CreatedAt { get; set; } = DateTime.Now; public DateTime StartTime { get; set; } public DateTime EndTime { get; set; }}
I have an AppUser model that uses Identity to handle user registration, login, etc. It has an AccountType attribute, that elsewhere has validation to make sure that its value is required to be "Performer" or "Venue" upon creation, which then gives an AppUser the Performer or Venue role.
public class AppUser : IdentityUser{ public string? AccountType { get; set; }}
My thought process:
Approach 1: add the Perfromer/Venue object as an attribute of the AppUser model. But it seems like there's no simple way to say "an AppUser should have X attribute/navigation property if the user has role A, but it should have Y attribute/navigation property if the user has role B."
Approach 2: make Performer and Venue inherit from some parent class like AccountTypeObj, and then include an AccountTypeObj as an attribute of AppUser. It seems like this could work, but I just don't know if this is the best way to do this.
Approach 3: create join tables for AppUsersPerformers and AppUsersVenues, and specify somewhere that these relationships are one-to-one. Something like this:
protected override void OnModelCreating(ModelBuilder modelBuilder){ modelBuilder.Entity<AppUser>() .HasOne(e => e.Performer) .WithOne(e => e.AppUser) .HasForeignKey<Performer>(e => e.PerformerId) .IsRequired(true);}
But I don't see how to specify that an AppUser has one Performer ONLY IF the AppUser has the Performer role, and that it should have one Venue otherwise.