Post

ASP.NET Core Playground - 1. Setup

I have been obsessing about something since I started creating APIs in ASP.NET Core. I want to find the way to create a perfect endpoint. What makes things even more fun is that .NET 7 was just released so every blog post and document that describes best practices is no longer relevant, because everything changed!

I spent some time and created a micro laboratory for testing different cases and approaches, and this is how I did it.

Database

I set up a docker container with MS SqlServer 2022. Since at this moment I’m more on the Dev side of DevOps I used C# and FluentDocker library to set everything up.

1
2
3
4
5
6
7
8
9
using Ductus.FluentDocker.Builders;

new Builder()
    .UseContainer()
    .UseImage("mcr.microsoft.com/mssql/server:2022-latest")
    .WithEnvironment("SA_PASSWORD=ServerAdminPassword666", "ACCEPT_EULA=Y")
    .ExposePort(1433, 1433)
    .Build()
    .Start();

Now I created a database using “Server Explorer” view in my Visual Studio 2022 and running a T-SQL script

1
CREATE DATABASE [PlaygroundDatabase]

I set database recovery mode to SIMPLE to save hard drive space since we really don’t care about ensuring the data is recoverable in case of corruption.

1
2
USE [master]
ALTER DATABASE [PlaygroundDatabase] SET RECOVERY SIMPLE

Then created a table inside that database

1
2
3
4
5
6
7
USE [PlaygroundDatabase]
CREATE TABLE [dbo].[WeatherForecasts](
    [Id] [uniqueidentifier] NOT NULL,
    [Date] [datetime2](7) NOT NULL,
    [TemperatureC] [int] NOT NULL,
    [Summary] [nvarchar](max) NULL
)

And filled it with 100.000 rows of data that contained 10.000.000 characters long string. This makes the database just over 1.5GB in size and ensures a nice and observable delay between each row when sending the data to Entity Framework Core.

1
2
3
4
5
6
7
8
9
10
11
USE [PlaygroundDatabase]

DECLARE @I Int = 0

WHILE (@I < 100000)
BEGIN
    INSERT INTO dbo.WeatherForecasts VALUES
        (NEWID(), GETUTCDATE(), @I, (REPLICATE('X', 10000000)))

    SET @I = @I + 1;
END

Backend

Now I created a simple WebAPI project with controllers, added Mapster and EntityFrameworkCore to it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net7.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Mapster" Version="7.3.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.1" />
  </ItemGroup>

</Project>

This is the model I used

1
2
3
4
5
6
7
public class WeatherForecast
{
    public Guid Id { get; set; }
    public DateTime Date { get; set; }
    public int TemperatureC { get; set; }
    public string? Summary { get; set; }
}

together with a very basic DbContext class

1
2
3
4
5
6
7
8
public class CustomDbContext : DbContext
{
    public DbSet<WeatherForecast> WeatherForecasts { get; set; } = null!;

    public CustomDbContext(DbContextOptions<CustomDbContext> contextOptions) : base(contextOptions)
    {
    }
}

that I configured in Program.cs this way

1
builder.Services.AddDbContext<CustomDbContext>(options => options.UseSqlServer("Server=localhost;Database=PlaygroundDatabase;User Id=sa;Password=ServerAdminPassword666;trustServerCertificate=true"));

I also added a DTO to be used in several different scenarios.

1
2
3
4
5
public class WeatherForecastDto
{
    public DateTime Date { get; set; }
    public int TemperatureC { get; set; }
}
This post is licensed under CC BY 4.0 by the author.