Search code examples
vb.netentity-frameworkviewmodel

How do I implement a ViewModel in this controller? MVC, EntityFramework


Database-first design. I want to implement a DoctorViewModel on my Doctor Edit page so that I can edit relationship between a Doctor and his patients.

The problem is that changes to the list of selected patients are not saving.

Controller code:

Function Edit(ByVal doctor As Doctor) As ActionResult
    If ModelState.IsValid Then

        db.Entry(doctor).State = EntityState.Modified
        db.SaveChanges()
        Return RedirectToAction("Index")

    End If

    Return View(doctor)

End Function

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)
        Get
            If _selectedPatients Is Nothing Then
                _selectedPatients = Doctor.Patients.[Select](Function(m) m.PatientID).ToList()
            End If

            Return _selectedPatients
        End Get
        Set(value As List(Of Integer))
            _selectedPatients = value
        End Set
    End Property

End Class

Doctor model:

Partial Public Class Doctor
    Public Property DoctorID As Integer
    Public Property Name As String
    Public Property Description As String
    Public Property DateCreated As Nullable(Of Date)
    Public Property CreatedBy As String
    Public Property IsDeleted As Nullable(Of Boolean)

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

End Class

Screenshots:

  1. Index page correctly shows Doctors and their Patients.

  2. Edit page shows all available patients and highlights selected patients. Changes to the Doctor properties can be saved here, but any change to the selection of patients is ignored. There are no errors.


Solution

  • This was the solution.

    I'm still not sure why it worked, ie. why changes to the Doctor fields (Name, Description, etc) would save, but changes to the sub-list of Patients would not.

    Function Edit(ByVal doctorViewModel As DoctorViewModel) As ActionResult
    
        If ModelState.IsValid Then
    
            'Grab the Doctor record and his associated patient records
            Dim item = db.Entry(Of Doctor)(doctorViewModel.Doctor)
            item.State = EntityState.Modified
            item.Collection(Function(i) i.Patients).Load()
    
            'Create new list of selected patients
            Dim pPatients As New List(Of Patient)
            For Each i In doctorViewModel.pSelectedPatients
                pPatients.Add(db.Patients.Find(i))
            Next
    
            'Replace entity's patients with the new list of patients
            item.Entity.Patients = pPatients
    
            'Save
            db.Entry(doctorViewModel.Doctor).State = EntityState.Modified
            db.SaveChanges()
    
            Return RedirectToAction("Index")
    
        End If
    
        Return View(doctorViewModel)
    
    End Function