I am trying to create booking type website, using ASP.NET Core API and Angular.
I got stuck on models / relations.
This is the Hotel
model class:
public class Hotel
{
[Key]
public int HotelId { get; set; }
// Hotel name
[Column(TypeName = "nvarchar(50)")]
public string HotelName { get; set; }
[Range(1,5,ErrorMessage = "Hotel Star Rating Value Must be in between of 1 and 5.")]
public byte Stars { get; set; }
// Hotel address linked to Hotel class.
public virtual ICollection<Address> HotelAddresses { get; set; }
// Hotel rooms linked to hotel class.
public virtual ICollection<Room> Rooms { get; set; }
}
This is the Address
model class:
public class Address
{
[Key]
public int AddressId { get; set; }
[Column(TypeName = "nvarchar(50)")]
public string Country { get; set; }
[Column(TypeName = "nvarchar(50)")]
public string City { get; set; }
[Column(TypeName = "nvarchar(50)")]
public string Street { get; set; }
// one-to-many.
[ForeignKey("hotel")]
public int HotelId { get; set; }
public virtual Hotel hotel { get; set; }
}
This is the Room
model class:
public class Room
{
[Key]
public int RoomId { get; set; }
[Column(TypeName ="nvarchar(50)")]
public string Name { get; set; }
[Column(TypeName = "nvarchar(250)")]
public string Description { get; set; }
public decimal price { get; set; }
// one-to-many
[ForeignKey("hotel")]
public int HotelId { get; set; }
public virtual Hotel hotel { get; set; }
}
Controller action method:
[HttpPost]
public async Task<ActionResult<Hotel>> PostHotel(Hotel hotel)
{
_context.Hotels.Add(hotel);
await _context.SaveChangesAsync();
return CreatedAtAction("GetHotel", new { id = hotel.HotelId }, hotel);
}
So the question is: what Am I doing wrong?
If nothing how am I supposed to create a record manually while I'm trying to have foreign keys and stuff?
I tried creating one-to-many relationship differently, lots of times, I thought it was about my code which was wrong and I thought by fixing my model classes Swagger UI would make it easier to create new record (to do post method basically) but I get confused when Swagger gives me format which considers me to write Hotel model and Ids too like aren't they supposed to be automated?
This is one of the reasons why you might prefer to use DTOs instead of your entity classes as input/output for you APIs. In this particular case you basically have a cyclic relationship between Hotel
and Address
which breaks not only swagger but will require to jump some hoops (if it is even possible) to post such model. As a quick fix you can make the hotel part of relationship optional (which is not ideal from EF Core design point of view):
public class Adress
{
// ...
[JsonIgnore]
public virtual Hotel? Hotel { get; set; }
}
But I would highly recommend to create a separate set of objects. Like for example:
public class CreateHotelRequest
{
public required string HotelName { get; set; }
[Range(1,5,ErrorMessage = "Hotel Star Rating Value Must be in between of 1 and 5.")]
public required byte Stars { get; set; }
public virtual ICollection<AddressDto> HotelAdresses { get; set; }
public virtual ICollection<RoomDto> Rooms { get; set; }
}
And for example AddressDto
:
public class AddressDto
{
public required string Country { get; set; }
public required string City { get; set; }
public required string Street { get; set; }
}