dotnetdevcsharp
dotnetdevcsharp

Reputation: 3980

EF Core 5 Many To Many relationships not working as should according to docs

According to the documentation, EF Core 5.0 supports many-to-many relationships without explicitly mapping the join table.

I'm having issues with the below in EF Core 5.0.9:

public List<Booking> GetAllBookingsForDay(int day, DateTime bookingDate)
{
     return db.Bookings
    .Where(w => w.IsActive == true & w.IsDeleted == false & w.DayOfWeek == day & w.Time >= bookingDate)
    .Include(c => c.Students)
    .ToList();
}

I have included Students as part of the query.

Booking.cs

public class Booking
{
    public int Id { get; set; }
    public int? DayOfWeek { get; set; }
    public DateTime? BookingDate { get; set; }
    public bool? IsAbsent { get; set; }
    public DateTime? Time { get; set; }
    public bool? HasCheckedIn { get; set; }
    public ICollection<Student> Students { get; set; }  // notice this
    public int? StudentId { get; set; }
    public bool? IsDeleted { get; set; }
    public bool? IsActive { get; set; }
    public string? CreatedBy { get; set; }
    public string? LastModifiedBy { get; set; }
}

Student.cs

public class Student
{   
    public int Id { get; set; }
    public int? Type { get; set; }
    public int? TeamId { get; set; }
    public string? FirstName { get; set; }
    public string? Surname { get; set; }
    public DateTime? DOB { get; set; }
    public decimal? Weight { get; set; }
    public decimal? Height { get; set; }
    public int? Gender { get; set; }
    public string? Photo { get; set; }
    public int? Age { get; set; }
    public ICollection<Booking> Bookings { get; set; } // notice here my link back 
     to bookings
   ...
 }

Nuget packages:

enter image description here

SQL database:

enter image description here

When I inspect the booking table, its empty does EF not automatically add into BookingStudent if so how do I tell ef core to add in the student? I have saved their StudentId into booking so why has it not created an entry.

It Created the booking table entry

enter image description here

In My head I should see the values 10 and 72 in booking student should I not.

But not the booking Student Entry ?. According to the docs it creates it automatically yeah but what about saving entries does it not still do that automatically.

enter image description here

At this stage I have not placed anything in my DBContext on create method as the docs say u dont need that any more???

This is how I save my student. As you see am filling in the foreign key of StudentId.

Booking newBooking = new Booking();
newBooking.DayOfWeek = DayNumber;
newBooking.BookingDate = BookingDate;
newBooking.Time=Helpers.Dates.GetDateZeroTime(selectedBookingDate.Date).Add(timePicker.Time);
newBooking.StudentId = StudentId;
newBooking.HasCheckedIn = false;
newBooking.IsActive = true;
newBooking.IsDeleted = false;
newBooking.IsAbsent = false;
await api.AddToBooking(newBooking);
await DisplayAlert(Constants.AppName, "Booking Created For Student", "OK");

My Add to booking which the api is calling in the web api is.

public Booking AddBooking(Booking  booking)
{
    db.Bookings.Add(booking);
    db.SaveChanges();
    return booking;
}

Edit 2

Is this what u mean

//Do i need to put the second param in for Student here ?
public Booking AddBooking(Booking booking, Student student)
{
        booking.Students.Add(student);
        db.Bookings.Add(booking);

        db.SaveChanges();
        return booking;
}

Upvotes: 1

Views: 577

Answers (1)

Ermiya Eskandary
Ermiya Eskandary

Reputation: 23602

If it's a many-to-many relationship, why do you have a StudentId property on Booking?

Remove the property first:

public class Booking
{
    public int Id { get; set; }
    public int? DayOfWeek { get; set; }
    public DateTime? BookingDate { get; set; }
    public bool? IsAbsent { get; set; }
    public DateTime? Time { get; set; }
    public bool? HasCheckedIn { get; set; }
    public ICollection<Student> Students { get; set; }
    public bool? IsDeleted { get; set; }
    public bool? IsActive { get; set; }
    public string? CreatedBy { get; set; }
    public string? LastModifiedBy { get; set; }
}

And then add the student you want (which will have an ID) to the ICollection of students you have for a booking.

booking.Students.Add(student);

That will trigger the EF many-many relationship.

Something like this:

var student = new Student { ... };

var newBooking = new Booking {
    Student = new List<Student> { student },
    ...
};

await api.AddToBooking(newBooking);

Upvotes: 3

Related Questions