Home > Net >  Define circular relationship for ICollection of bookings in entity framework
Define circular relationship for ICollection of bookings in entity framework

Time:11-18

I am trying to add a circular relationship in my project. I have the following problem: My database consists of a table with bookings (on a specific machine). Since the machines can handle multiple bookings at once, I have another table that stores all the (overlapping) parallel bookings. How can I now attach the overlapping bookings to the original booking element? I would like to access the overlaps like this:

var bookings = dbContext.Booking.Include(x => x.OverlapBookings).ToList();
foreach (var booking in bookings)
{
    var overlaps = booking.OverlapBookings;
    ...

However, when trying to add the migration, I am running into the following error:

Unable to determine the relationship represented by navigation 'BookingDbModel.OverlapBookings' of type 'ICollection'. Either manually configure the relationship, or ignore this property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.

How can I now define this circular relationship?

Here are the classes:

public class BookingDbModel
{
    public int id { get; set; }
    public string Name { get; set; }
    public string Client { get; set; }
    public string Machine { get; set; }
    public DateTime StartTime { get; set; }
    public DateTime EndTime { get; set; }
    public ICollection<OverlapBookingDbModel> OverlapBookings { get; set; }
}

and

public class OverlapBookingDbModel
{
    public int OriginalBookingId { get; set; }
    public BookingDbModel OriginalBooking { get; set; }
    public int TargetBookingId { get; set; }
    public BookingDbModel TargetBooking { get; set; }
}

CodePudding user response:

With the following manual relationship definition, the entity updated successfully and all the models are now accessible with only one dbContext call:

DbContext.cs

public class ApplicationDbContext : DbContext
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
    : base(options)
    {
    }
    public DbSet<BookingDbModel> Booking { get; set; }
    public DbSet<OverlapBookingDbModel> OverlapBooking { get; set; }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<OverlapBookingDbModel>()
            .HasOne(p => p.OriginalBooking)
            .WithMany(b => b.OverlapBookings)
            .HasForeignKey(k => k.OriginalBookingId);

        base.OnModelCreating(modelBuilder);
    }
}

I can now access all related Overlapbookings like this:

var testbookings = dbContext.Booking.Include(x => x.OverlapBookings).ThenInclude(y => y.TargetBooking).FirstOrDefault(x => x.Id == 12);
  • Related