Data Access has been discontinued. Please refer to this page for more information.

Retrieving Cars from the Database and Disposing the Context

In this step you will add functionality to the MainViewModel which allows the retrieval of cars from the database and disposes of the context when it is no longer needed.

  1. In the constructor of the model add a call to a method which will be defined shortly - RetrieveCarsToDisplay().

    this.RetrieveCarsToDisplay();
    
    Me.RetrieveCarsToDisplay()
    
  2. Define the RetrieveCarsToDisplay() method. It saves the id of the currently selected car, retrieves the cars from the database according to the currently active filter and then restores the selected car using its id. At the end it updates the status according to the number of retrieved cars. As you can see, the retrieved cars are exposed through the CarsToDisplay property to which a RadGridView control on MainWindow is bound.

    private void RetrieveCarsToDisplay()
    {
        this.ClearCache();
        int? selectedCarId = null;
        //save the Id of the currently selected car
        if (this.SelectedCar != null)
        {
            selectedCarId = this.SelectedCar.CarID;
        }
        if (string.IsNullOrEmpty(this.carMakerFilter))
        {
            //retrieve all cars
            this.CarsToDisplay = this.context.Cars.ToList();
        }
        else
        {
            //retrieve cars which comply to the filter
            this.CarsToDisplay = this.context.Cars.Where(car => car.Make == this.carMakerFilter).ToList();
        }
        //restore the selected car using its saved Id
        if (selectedCarId.HasValue)
        {
            this.SelectedCar = this.CarsToDisplay.FirstOrDefault(car => car.CarID == selectedCarId);
        }
        this.Status = string.Format(STATUS_MESSAGE, this.CarsToDisplay.Count); 
    }
    
    Private Sub RetrieveCarsToDisplay()
        Me.ClearCache()
        Dim selectedCarId As Integer? = Nothing
        'save the Id of the currently selected car
        If IsNothing(Me.SelectedCar) = False Then
            selectedCarId = Me.SelectedCar.CarID
        End If
        If String.IsNullOrEmpty(Me.CarMakerFilter) Then
            'retrieve all cars
            Me.CarsToDisplay = Me._context.Cars.ToList()
        Else
            'retrieve cars which comply to the filter
            Me.CarsToDisplay = Me._context.Cars.Where(Function(car) car.Make = Me.CarMakerFilter).
                                ToList()
        End If
        'restore the selected car using its saved Id
        If selectedCarId.HasValue Then
            Me.SelectedCar = Me.CarsToDisplay.FirstOrDefault(Function(car) car.CarID = selectedCarId)
        End If
        Me.Status = String.Format(STATUS_MESSAGE, Me.CarsToDisplay.Count)
    End Sub
    
  3. Define the ClearCache() method. It is called from RetrieveCarsToDisplay and clears the context cache, so that changes to single properties can be detected whenever retrieving cars.

    private void ClearCache()
    {
        if (this.CarsToDisplay != null)
        {
            this.context.ClearChanges();
        }
    }
    
    Private Sub ClearCache()
        If IsNothing(Me._context) = False Then
            Me._context.ClearChanges()
        End If
    End Sub
    

Disposing the context

Whenever an OpenAccessContext object is initialized, a connection to the database is opened. This connection stays opened as long as the Context object lives. It is a good practice to dispose of the Context object when it is no longer needed. In the current view model the context is no longer needed once the view closes and the view model is disposed.

  1. In MainViewModel implement the IDisposable interface to make it disposable. In the Dispose method, dispose the OpenAccessContext object. This way when the view model is no longer needed and thus disposed, the context will be disposed as well.

    public void Dispose()
    {
        //The context is local to the ViewModel and must be disposed together with it
        if (this.context != null)
        {
            this.context.Dispose();
        }
    }
    
    Public Sub Dispose() Implements IDisposable.Dispose
        'The context is local to the ViewModel and must be disposed together with it
        If IsNothing(Me._context) = False Then
            _context.Dispose()
        End If
    End Sub
    

Next step: Initializing MainViewModel