0

When I call SaveChanges(), Entity Framework is not saving my changes.

Here's my code:

Model

Partial Public Class Doctor
    Public Property DoctorID As Integer
    ...

    Public Overridable Property Patients As ICollection(Of Patient) = New HashSet(Of Patient)

End Class

Viewmodel

Public Class DoctorViewModel

    Public Property Doctor As Doctor
    Public Property AllPatients As IEnumerable(Of SelectListItem)

    Private Property _selectedPatients As List(Of Integer)

    Public Property pSelectedPatients As List(Of Integer)
    ...
    End Property

End Class

Controller snippet with the problem. To illustrate the problem I'm clearing the list of patients every time an edit is performed.

Function Edit(ByVal doctorViewModel As DoctorViewModel) As ActionResult

    If ModelState.IsValid Then

        doctorViewModel.Doctor.Patients.Clear()

        db.Entry(doctorViewModel.Doctor).State = EntityState.Modified

        db.SaveChanges()

        Return RedirectToAction("Index")

    End If

    Return View(doctorViewModel)

End Function

I would expect the list of patients to be cleared, and records to be deleted from DoctorPatient. However these changes don't "take".

Any suggestions on how to debug or fix?

Screenshots:

  • During Edit I clear the list of patients from the doctor
  • After saving the record, the DoctorPatient records have not been deleted, and the relationship between doctor and patient objects is still on the page
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
TheLeb
  • 144
  • 1
  • 11
  • So, you're loading doctor 123 and all 20 of his patients, and then you're trying to make EF delete all records from the DoctorPatient table where doctorID = 123, by clearing the patients list, setting the doctor state as modified, and saving? – Caius Jard Jun 25 '20 at 16:39
  • That's the idea. I created this project to be a minimal example of a problem I'm having with a real-world application. Because the product is the database table(s) I inherited I decided to go with Entity Framework but I've been struggling to learn it. Some of the fundamentals are still unclear. – TheLeb Jun 25 '20 at 16:45

2 Answers2

1

I've never known clearing a collection to remove entities from a database. I would expect it to be more like:

For Each p as Patient In Doctor.Patients
    db.Patients.Remove(p)
Next p

db.SaveChanges()

Incidentally, it's not really the design intent to put db entities into your viewmodels; db entities tend to stay as devices for shuttling data between the middle layer and the db, and viewmodels are for shuttling data between the middle layer and the UI. The middle layer carries out mappings from one to the other

Caius Jard
  • 72,509
  • 5
  • 49
  • 80
  • Thank you! I want to remove relationship between doctor and patient, not delete the patient. Added an answer to my own question to accomplish this – TheLeb Jun 25 '20 at 16:52
  • How would you separate the layers of the application in this case? I don't want to start mixing up my layers this early in the project – TheLeb Jun 25 '20 at 16:53
0

Here's the code change that solved my problem. I don't know why it worked.

Credit to SO user Stritof who provided the answer.

Function Edit(ByVal doctorViewModel As DoctorViewModel) As ActionResult

    If ModelState.IsValid Then

        Dim item = db.Entry(Of Doctor)(doctorViewModel.Doctor) '<-- this was it
        item.State = EntityState.Modified
        item.Collection(Function(i) i.Patients).Load()

        item.Entity.Patients.Clear()

        db.Entry(doctorViewModel.Doctor).State = EntityState.Modified

        db.SaveChanges()

        Return RedirectToAction("Index")

    End If

    Return View(doctorViewModel)

End Function
TheLeb
  • 144
  • 1
  • 11