Click here for an updated post explained with GIFs.
Now that we have the database in our SQL Server Project a DbContext, how do we pass the data to the view? We can construct asynchronous methods in a provider class to call the data in the controller.
Before we move on, if you don’t have your SQL Server Project or your DbContext, click here to see how you can configure the SQL Server Project and here to learn how you can reverse engineer to generate a DbContext.
Overview
- Create Class Libraries (.NET Framework) and folders under them
- Add a Data Transfer Object (DTO), a replica of a model that will be used to transfer data
- Add a Provider Class and create async methods
- Call the async methods from the controller and pass the data to the view
Note how we are following a folder structure we created in this post.
Adding Class Libraries
Create a Class Library (.NET Framework). Configure the file path to where your .NET Framework Web Application is. I will be placing the Class Library under ’02 – Application’ folder as we created earlier here. This class library will hold the provider classes.
Create another Class Library that will hold our models (DTOs) and View Models. You could append. Domain to the project name. Again, configure the location to ’03 – Domain’ folder.
Return to the .NET Framework Web App and right click the solution to add the Class Libraries we just created (‘Add Existing Project’). Drag the added tasks into the corresponding folders. Refer to step 3 of this blog post here to learn how you can add existing project.
Right click the Class Library and add Interfaces and Providers folders under ’02 – Application’ folder and Models and ViewModels folders under ’03 – Domain’ folder.’
Creating a DTO and a Provider Class
Add a ‘CustomerDto’ class under ’03 – Domain > Models’ folder. Add the properties (fields) with getters and setters.
In this folder structure that I am working in, notice how the CustomerDto is stored in the Models folder under ’03 – Domain’, while the actual Customer Model is stored in the Models folder under ’04 – Database’.
**Before moving on, we need to override DbContext.OnConfiguring(DbContextOptionsBuilder) method in the DatabaseContext to configure the database to be used for this context. Click here for a post explaining how you can set that up.
Now we can add a ‘CustomerProvider’ class under ’02 – Application > Providers’ folder.
- Declare the DbContext as private readonly
- Create constructors (constructor chaining is used) that will instantiate the DbContext using Dependency Injection
Add a GetCustomersAsync() method that will store data from DbContext in a list of CustomerDto using LINQ.
- Task<> represents a single operation that usually executes asynchronously.
- In our example, we are using LINQ to .Select variable (Id, Name, & Email) to store each of them in the variables of CustomerDto object. We are using .SingleOrDefaultAsync() method to return the CustomerDto object.
- .AsNoTracking() is conventionally used because entities returned will be cached in the DbContext by default, rendering errors when we are calling an entity in different places at the same time.
We can use .ToListAsync() method to return a list of objects as demonstrated below.
Along the way, you might have to install packages (Microsoft.EntityFrameworkCore) to add a reference to the DbSet.
NOTE: We will need to install couple of Nuget packages to use the Task class and SqlClient for DbContext to interact with the Sql Server. Without the installations, you might encounter errors like “Could not load file or assembly ‘System.Threading.Tasks.Extensions'” like the one shown below:
Click here to fix the “Could not load file or assembly ‘System.Threading.Tasks.Extensions’ or one of its dependencies” error and here for the “Failed to load \bin\x86\SNI.dll” error.
That is pretty much it for creating DTO and async method in the provider class. Now we can call the method from the controller and pass it to the view!
Creating a Controller and View
1) In our examples, we will be using IndexController. Create constructors to instantiate the providers. I can call .GetCustomerAsync() method that I created in the provider class and store it in a variable. We will then pass this variable to the view.
2) This is how our razor page and the view will look like!
How our Demo_01 database looks like
Hope that helped!