Create a Blazor Server Application with Entity Framework Core 8

Quentin DESTRADE

Friday 16 May 2025

  • Tutorials

In this tutorial, we will create a Blazor Server application that interacts with a DB2 for i database via NTi EF Core. We will implement a simple CRUD to manipulate the data.

Main image of the article “Create a Blazor Server Application with Entity Framework Core 8”

Introduction

In this tutorial, we will create a Blazor Server application that interacts with a DB2 for i database via NTi EF Core. We will implement a simple CRUD to manipulate the data.

We will use an example managing products, categories, and orders:

Step 1 - Project Creation and Configuration

Create a new .NET project, and choose the blazor Web App project template. In the project configuration options, select the Server Interactive Render Mode, and make sure to choose .NET 8.0.

Add the required packages:

dotnet add package Aumerial.Data.NTi
dotnet add package Aumerial.EntityFrameworkCore
dotnet add package Microsoft.EntityFrameworkCore.Design

Add the connection string in appsettings.json, and specify the default schema in which all created entities will be placed:

{
    "ConnectionStrings": {
        "DefaultConnection": "server=myserver;user=myuser;password=mypassword;database=mydb"
    }
}

Step 2 - Defining the Entities

Create a Models folder to organize your entities, and add the following classes to model your data.

  • Category.cs

A category can contain multiple products.

public class Category
{
    public int Id { get; set; }
    public string Name { get; set; }
    public ICollection<Product> Products { get; set; }
}
  • Product.cs

A product belongs to a category and can be linked to multiple orders.

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string description { get; set; }
    public decimal Price { get; set; }
    public int stockQuantity { get; set; }
    public decimal Weight { get; set; } 
    public bool IsAvailable { get; set; }

    public int CategoryId { get; set; }
    public Category Category { get; set; }
}
  • Order.cs

An order can contain multiple products.

public class Order
{
    public int Id { get; set; }
    public DateTime OrderDate { get; set; }
    public DateTime? DeliveryDate { get; set; }
    public decimal TotalAmount { get; set; } 

}

Step 3 - DbContext Configuration

Add a class AppDbContext that inherits from DbContext, to manage the entities and their relationships.

using Microsoft.EntityFrameworkCore;

public class AppDbContext : DbContext
{
    public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }

    public DbSet<Product> Products { get; set; }
    public DbSet<Category> Categories { get; set; }
    public DbSet<Order> Orders { get; set; }

     protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
       
    }
}

Step 4 - Configuration in Program.cs

To allow the application to use DbContext, you must configure it in Program.cs and register it as a service via dependency injection for your Blazor components.

var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<AppDbContext>(options =>
    options.UseNti(connectionString));
  • AddDbContext is recommended for most Blazor Server applications. The DbContext is instantiated with a Scoped lifetime, meaning it is recreated for each user request.
  • AddDbContextFactory is used in scenarios where the DbContext must be created dynamically, such as background tasks or multi-threaded processing.

Step 5 - Creating and Managing Migrations

Generate an initial migration to synchronize your entities with the database. This command will create a file in the Migrations folder containing the SQL instructions to create your tables:

dotnet ef migrations add InitialCreate

Then apply the migration to update the database and create the tables:

dotnet ef database update

article 19

To add a new table or modify an existing table, it's the same principle. Create your entities, add them in AppDbContext, and generate a new migration to take the new table into account:

dotnet ef migrations add newEntity

Update the database to include the new table:

dotnet ef database update

If you made a mistake, you can delete the last migration before applying it:

dotnet ef migrations remove

Si vous souhaitez revenir à une version antérieure de la base, vous pouvez spécifier directement le nom de la migration:

dotnet ef database update <NomMigrationPrécédente>

Step 6 - Adding Initial Data Set

Add a data set into the database after applying the migrations. Do this in program.cs after registering the services:


using (var scope = app.Services.CreateScope())
{
    var context = scope.ServiceProvider.GetRequiredService<AppDbContext>();

    var categories = new List<Category>
        {
            new Category { Name = "Electronics" },
            new Category { Name = "Books" },
            new Category { Name = "Home Appliances" },
            new Category { Name = "Fashion" },
            new Category { Name = "Toys" }
        };

    context.Categories.AddRange(categories);


    var products = new List<Product>
        {
            new Product { Name = "Smartphone", Price = 500, stockQuantity = 10, Category = categories[0], IsAvailable = true },
            new Product { Name = "Laptop", Price = 1200, stockQuantity = 5, Category = categories[0], IsAvailable = true },
            new Product { Name = "Washing Machine", Price = 300, stockQuantity = 8, Category = categories[2], IsAvailable = true },
            new Product { Name = "T-Shirt", Price = 20, stockQuantity = 50, Category = categories[3], IsAvailable = true },
            new Product { Name = "Children's Book", Price = 15, stockQuantity = 100, Category = categories[1], IsAvailable = true },
            new Product { Name = "Toy Car", Price = 30, stockQuantity = 20, Category = categories[4], IsAvailable = true },
            new Product { Name = "Microwave Oven", Price = 250, stockQuantity = 6, Category = categories[2], IsAvailable = true },
            new Product { Name = "Jeans", Price = 40, stockQuantity = 30, Category = categories[3], IsAvailable = true }
        };

    context.Products.AddRange(products);


    var orders = new List<Order>
        {
            new Order { OrderDate = DateTime.Now.AddDays(-10), DeliveryDate = DateTime.Now.AddDays(-7), TotalAmount = 750 },
            new Order { OrderDate = DateTime.Now.AddDays(-5), DeliveryDate = DateTime.Now.AddDays(-3), TotalAmount = 600 },
            new Order { OrderDate = DateTime.Now.AddDays(-2), DeliveryDate = null, TotalAmount = 290 }
        };

    context.Orders.AddRange(orders);


    var orderProducts = new List<OrderProduct>
        {
            new OrderProduct { Order = orders[0], Product = products[0] },
            new OrderProduct { Order = orders[0], Product = products[1] },
            new OrderProduct { Order = orders[0], Product = products[3] },

            new OrderProduct { Order = orders[1], Product = products[4] },
            new OrderProduct { Order = orders[1], Product = products[5] },
            new OrderProduct { Order = orders[1], Product = products[6] },

            new OrderProduct { Order = orders[2], Product = products[2] },
            new OrderProduct { Order = orders[2], Product = products[7] }
        };

    context.OrderProducts.AddRange(orderProducts);


    context.SaveChanges();
}

Step 7 - Generating CRUD Pages

Automatically add the CRUD pages for the entities:

Right-click on the Pages folder > Add > Razor Components with EF (CRUD).

For the Products CRUD, select Product as the model and AppDbContext as the context.

Step 8 - Adding a Field for Image UPLOAD (BLOB)

We will add an Image field of type byte[] to store the image data in the database.

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public decimal Price { get; set; }
    public int StockQuantity { get; set; }
    public decimal Weight { get; set; }
    public bool IsAvailable { get; set; }

    public int CategoryId { get; set; }
    public Category Category { get; set; }

    // New field for the image
    
    [Column(TypeName = "BLOB(1M)"), DataType(DataType.Upload)]
    public byte[] Image { get; set; }
}

We generate a migration to add the new field to the products table, then update the database.

dotnet ef migrations add AddProductImage
dotnet ef database update

Next, you need to modify the EditProductand CreateProduct components to add a field for uploading the image:

 
@if (Product?.Image != null && Product.Image.Length > 0) {

Current image :

} else {

No image available

}

And the method to handle the upload:

    private async Task UploadFile(InputFileChangeEventArgs e)
    {
        var file = e.File;

        if (file != null)
        {
            using var memoryStream = new MemoryStream();
            await file.OpenReadStream().CopyToAsync(memoryStream);
            Product.Image = memoryStream.ToArray();
        }
    }

Visual of the resulting CRUD on the product index page:

article 19

Back