ViewModels

What is a ViewModel?

A ViewModel is like a standard Model in C#.NET Core in that it allows us to work with data which is being retrieved from a data source whether persistent or not. It’s normal that your standard Model would mirror the fields in your database, for example let us consider a table called ‘Login’.

Field Data Type
UserId Integer
Username String
Password String
Firstname String
Surname String

The code for this Model would more than likely look something like the following…

namespace ApplicationNamespace.Models
{
    public class Login
    {
        public int UserId { get; set; }
        public string Username { get; set; }
        public string Password { get; set; }
        public string Firstname { get; set; }
        public Lastname { get; set; }
    }
}

This covers all the content within the table itself and we can easily use Entity Framework to query this table and display its data. In this case your form code might look like below.

// get the first 100 results
var result = context.Login.Take(100);
var listResults = result.ToList();

// set the datasource of the DataGridView control
dgLogins.DataSource = listResults;

That is all straightforward and gives us some nice tidy, clean syntax in the view (form that is visible to the user) itself. However, what happens if we need to join data together from multiple tables, or multiple objects from our data source. That is exactly where a ViewModel comes into play.

A ViewModel allows us to pull all the information together from multiple Model’s into a Model which is streamlined, efficient and contains the exact information we need to display to our users in the view. This is particularly useful when we are looking to use complex queries in relational database systems such as SQL server.

Deciding which Models to use

The first thing we need to do before we can create our ViewModel is ensure that we have the standard Model for that set of data created in our application.

image-20211116212341047

In the diagram above we can see a prime example of where a ViewModel would come in useful. In this case we have a Login Model which contains the standard Login information for a user. We then have a Profile model which could contain further information such as their name, address, hobbies etc.

To display this information on a ‘user profile’ screen the best thing to do would be to create a ViewModel which combines these two models and allows us to display the information back to the user.

We can assume in the case of this article that the two tables from our relational database (SQL in this case) have a link or relationship of some sort. In this case the Profile information has a UserId which is a foreign key of the Login table.

Querying the Data

Now that we have decided which existing (standard) Model’s to use we can write our query using LINQ syntax in the controller.

What is LINQ?

LINQ stands for Language Integrated Query and allows the .NET platform to add native data querying tools into C# or Visual Basic whilst bridging the mismatch between regular querying languages such as SQL and the programming language itself. You’ll see that queries written in LINQ are much clearer and almost pseudocode like in its syntax 😊

The query might look something like below. Note that this query is currently only searching for a user with the UserId 1. This is therefore a static query. Have a think about how you could make this dynamic in your application.

// load the viewModel
UserProfileViewModel UserProfile = new UserProfileViewModel();

// create a LINQ query which contains a JOIN
var result = (from ud in context.Login
         join pd in context.Profile
               on ud.UserId equals 2 into profileData
         from udpd in profileData.DefaultIfEmpty()
                              
         // select the format you want to return using the format of the viewModel
         select new UserProfileViewModel()
         {
             Name = ud.Firstname + " " + ud.Lastname,
             AddressLine1 = udpd.AddressLine1,
             AddressLine2 = udpd.AddressLine2,
             City = udpd.City,
             Hobbies = udpd.Hobbies
                 
         }).FirstOrDefault();

Let us look a little closer at this and highlight some of the key areas of the query. LINQ is a whole other subject however to aid the understanding of ViewModel’s we will break this query down briefly in this article. We can split this query into two main sections. Section 1 is the query of the data itself.

image-20211116212911809

Section 2 is where we pass the data we have collected from our query into our new ViewModel. We have not created the ViewModel itself just yet but will shortly.

image-20211116213112298

In this code we create a new instance of our ViewModel which we will name UserProfileViewModel.

image-20211116213136200

The name here isn’t important although it makes sense to name this using a combination of the names of the models involved followed by the words View & Model. This makes it clear that is a ViewModel made from User information and Profile information.

Creating the ViewModel itself

Now that we have our query in place, we need to create our ViewModel to allow us to display this data in the View. The following is an example of a ViewModel for the scenario in this article.

using ApplicationNamespace.Models;

namespace ApplicationNamespace.ViewModels
{
    public class UserProfileViewModel
    {
        public Login Login { get; set; }
        public Profile Profile { get; set; }
        public string Name { get; set; }
        public string AddressLine1 { get; set; }
        public string AddressLine2 { get; set; }
        public string City { get; set; }
        public string Hobbies { get; set; }
    }
}

The ViewModel is made up of both the Login & Profile Model’s along with all the new field names and their respective datatypes. Note there are some subtle differences, first we must include using ApplicationNamespace.Models, secondly, we set the namespace for this class with ViewModels.

Displaying the Data in the Form (View)

Now we have our query and ViewModel created we can focus on returning this data in the view. You should investigate the different ways of returning data. Like a standard Model I can now call the new field names from the ViewModel that we called UserProfileViewModel like below.

// show the users preferred name
MessageBox.Show(result.Name, "Full Name");
MessageBox.Show(result.City, "City");

And that’s it, you now have a query linking two pieces of data together and a view showing this information to your users 😊