DotVVM is an ASP.NET framework that allows us to create web applications using the MVVM (View-Model Model) design pattern using C# and HTML. In this tutorial, we will learn how to create CRUD (Create, Read, Update, and Delete) operations using a relational database with PostgreSQL, from ASP.NET Core.
Want to know what the steps are to create a DotVVM app? To do this, you can review this article - Steps to Create an MVVM Application (Model-View-ViewModel) with DotVVM and ASP.NET Core.
Introduction to ADO.NET Entity Framework
ADO.NET Entity Framework is an Object Relational Mapping (ORM) framework. It is designed to allow us to create data access applications by programming in a conceptual application model instead of programming directly into a relational storage scheme. The goal is to reduce the amount of code and maintenance required for data-oriented applications.
Resources required
To work with PostgreSQL ASP.NET Core with DotVVM, the recommended tools for setting up our work environment are as follows,
- Visual Studio 2019
- The workload in Visual Studio 2019: Developing ASP.NET and Web.
- DotVVM extension for Visual Studio 2019
- PostgreSQL
The database in PostgreSQL
For this tutorial article, let's create a sample database in PostgreSQL, which allows us to work with user data and then implement CRUD operations on ASP.NET Core.
To establish our database we can use the pgAdmin4 tool, which is usually included when installing PostgreSQL. When you create the schema, the SQL code for creating our user table is as follows,
- CREATE SEQUENCE id_seq
- INCREMENT 1
- START 1
- MINVALUE 1
- MAXVALUE 9223372036854775807
- CACHE 1;
- CREATE TABLE person
- (
- id_ integer NOT NULL DEFAULT nextval('id_seq'::regclass),
- firstname character varying(45) COLLATE pg_catalog."default" NOT NULL,
- lastname character varying(45) COLLATE pg_catalog."default" NOT NULL,
- username character varying(45) COLLATE pg_catalog."default" NOT NULL,
- city character varying(45) COLLATE pg_catalog."default" NOT NULL,
- country character varying(45) COLLATE pg_catalog."default" NOT NULL,
- postalcode integer NOT NULL,
- about character varying(45) COLLATE pg_catalog."default" NOT NULL,
- enrollmentdate timestamp without time zone NOT NULL,
- CONSTRAINT person_pkey PRIMARY KEY (id_)
- )
Here the primary key id_ is in a sequence so that the value of this key is self-incremental.

Project in Visual Studio 2019
Now that the database is set, then we can start developing our solution in Visual Studio. In this new project we will have three parts,
- Data Access Layer (DAL): To handle the connection to PostgreSQL and database access.
- BL (Business Layer): for the management of the services and the logic of the application domain.
- PL: to work with the presentation layer of the application, in this case, with DotVVM.
To get started, we'll create a new project in Visual Studio 2019 of the type DotVVM Web Application,

When creating the project, the DotVVM setup wizard allows you to select a number of options with settings, styles, and templates already preset,

In this case, we will leave everything like this and create the project. When you create a DAL and BL folder for the data access layer and business logic respectively, in the solution you'll have something like this,

Connection to PostgreSQL
All right, as a first point, we're going to relate our project to the database created in PostgreSQL. In the Entity Framework, there are two approaches, the first Code-First, which allows us to generate the database through classes, and the second, Database-First, which allows us to generate feature classes from an existing database. As expected, in this case, we will use the Database-First approach. To meet this goal, we will need to install three Nuget packages,
- Microsoft.EntityFrameworkCore.Design
- Microsoft.EntityFrameworkCore.Tools
- Npgsql.EntityFrameworkCore.PostgreSQL
Then we will need to insert command from the package manager console. This console can be activated from the Options Menu -> View -> Other Windows -> the Package Management Console.

In this console we will insert the following command,
- Scaffold-DbContext "Host=hostname;port=portnumber;Username=username;Password=pass;Database=databasename" Npgsql.EntityFrameworkCore.PostgreSQL -OutputDir DAL/Entities
Where,
- Hostname, is the name of the server from which the database is located. Example: localhost.
- Portnumber, host port. PostgreSQL is usually located on port 5432.
- Username, database username.
- Password, password of the user who will access the database.
- Database, database name.
Also,
- -OutputDir, with this keyword we can indicate where the files will be generated.
- -Table, additional abbreviation in case you want to indicate the specific tables to generate in our data access layer.
When you enter the command correctly, you'll have something like this,

Where Person is the class that is associated with the entity with the same name in the database and the DBContext is where the corresponding configurations are located.
The Person class is defined as follows,
- public partial class Person
- {
- public int Id { get; set; }
- public string Firstname { get; set; }
- public string Lastname { get; set; }
- public string Username { get; set; }
- public string City { get; set; }
- public string Country { get; set; }
- public int Postalcode { get; set; }
- public string About { get; set; }
- public DateTime Enrollmentdate { get; set; }
- }
And the DBContext, which has the configuration with the database, whose main method OnConfiguring will look something like this,
- protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
- {
- if (!optionsBuilder.IsConfigured)
- { optionsBuilder.UseMySQL("host=localhost;port=5432;username=<Username>;password=;database=<Database_name>");
- }
- }
Now, it is not the most appropriate for the database connection string to be specified in this OnConfiguring method, for this, we will specify the connection string in the appsettings.json file as follows,
- "AllowedHosts": "*",
- "ConnectionStrings": {
- "DefaultConnection": "host=localhost;port=5432;username=<Username>;password=;database=<Database_name>");
- }
Then, in the Startup class in ConfigureServices method we add as a service to the DBContext and refer to the DefaultConnection property specified in the appsettings.json file:
- public void ConfigureServices(IServiceCollection services)
- {
- services.AddEntityFrameworkNpgsql ()
- .AddDbContext<DBContext>(options =>
- {
- options. UseNpgsql(Configuration.GetConnectionString("DefaultConnection"));
- });
- }





Join the conversation! Your thoughts help the community grow.