Serverless relational code first database apps in Azure
By: Philipp Bauknecht
Tags: Azure, Serverless, Postgresql, Postgres, Azure Functions

Let’s write some code!

With the database ready in the cloud we can finally start with the app by creating a new empty C# Azure Functions app in Visual Studio.

To use EntityFramework Core in a Function app we need some packages from Nuget. So let’s add these:

Microsoft.Azure.Functions.Extensions, to we can use Dependency Injection

to we can use Dependency Injection Microsoft.EntityFrameworkCore (3.1.4)

Microsoft.EntityFrameworkCore.Design (3.1.4)

Microsoft.EntityFrameworkCore.Tools (3.1.4)

Npgsql.EntityFrameworkCore.PostgreSQL (3.1.4), PostgreSQL provider for EntityFramework Core

Important: At the time of writing this only works with version 3.1.4 and NOT with 5.x of the EntityFramework and Npgsql packages!

Step 1: Code first model

Let’s create a simple model of a customer in a new customer namespace:

Step 2: Database Context

Now we need to add this model to a context deriving from DbContext to add this model as a table to our database:

Step 3: Service

To serve the data to the view (in our case a http function) we want to have a service that loads the model data from the DbContext and returns the data as a view model. So first the view model:

To make our code testable let’s introduce an interface for our service with the CRUD methods:

The implementation of the service gets the DbContext injected:

Implement the CreateAsync method:

Implement the GetAsync method:

Implement the UpdateAsync method:

Implement the DeleteAsync method:

Step 4: Configure dependency injection

Dependency Injection helps us to wire everything together and also to provide settings like the connection string. The connection is best placed in local.settings.json (Azure Key Vault for production):

For dependency injection we need a new class Startup.cs in the root namespace. Here we can retrieve the connection string and register both the context and the service:

Step 5: Enable design-time context creation and adding a migration

So this is some wisdom from a great blog post by Jeff Hollan on this matter: https://dev.to/azure/using-entity-framework-with-azure-functions-50aa

Implement a IDesignTimeDbContextFactory to help entity framework discover our context:

Next we need to make sure our project’s dll is in the right spot for entity framework. So add this copy task to the project’s csproj:

Now we can finally run our first migration and update the database in the Package Manager Console. Also note that I added the connection string as an environment variable as EntityFramework doesn’t now it from our local.settings.json:

$env:SqlConnectionString="Server=tcp:mySqlServerStuffxxx"

Add-Migration InitialCreate

Update-Database

Step 6: Http Functions

Now that the database is up to date, let’s also add 4 functions with http triggers to expose the customer CRUD operations as REST-style endpoints. Each function class and Run method needs to be modified from static to non static and we need to inject the ICustomerService into each function class.

Function to create a new customer

Function to get a list of customers

Function to update a customer

Function to delete a customer

Step 7: Test with Postman

With all functions in place our code is ready for some testing. So let’s spin up Postman to test our CRUD API: