Home > Back-end >  Load page before content (data from database)
Load page before content (data from database)

Time:11-20

I am creating my first Blazor web application for self education purposes. There is a simple database with data. Dataset is currently rather small. However while clicking on page link it takes some 1-2 seconds to load. Just wondering that how long it would take if dataset would consist of larger amount of items. Is there a way to load page first and then populate the data?

public class EmployeesBase : ComponentBase:

[Inject]
protected IRepository Repository { get; set; }
protected List<BlazorCompanyManager.Data.Employee> employees;

protected override void OnInitialized()
{
  this.employees = this.Repository.GetEmployees();
}

public interface IRepository:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace BlazorCompanyManager.Data
{
  public interface IRepository
  {
    public List<Employee> GetEmployees();

    public Employee GetEmployee(Guid id);

    public bool UpdateEmployee(Employee employee);

    public void AddEmployee(Employee employee);

    public void DeleteEmployee(Guid id);
  }
}

public class Repository : IRepository:

protected readonly ApplicationDbContext dbContext;

public Repository(ApplicationDbContext db)
{
  this.dbContext = db;
}

public List<Employee> GetEmployees()
{
  return this.dbContext.EmployeeTable.ToList();
}

I have tried to make it work with OnInitializedAsync and other override methods, but got no success so far. Could anyone give some idea on how it can be done?

CodePudding user response:

You''re running an async code block synchronously, thus blocking the UI thread.

this.dbContext.EmployeeTable.ToList()

should look like this:

public async ValueTask<List<Employee>> GetEmployeesAsync()
{
    using var dbContext = this.DBContext.CreateDbContext();
    var list = await dbContext
    .EmployeeeTable
    .ToListAsync() 
    ?? new List<TRecord>();
    return list;
}

To do this you also need to move to an IDbContextFactory in your Repository. You can no longer rely on a single DbContext.

protected virtual IDbContextFactory<MyDbContext> DBContext { get; set; } = null;

public xxxxxRepository(IConfiguration configuration, IDbContextFactory<MyDbContext> dbContext)
    => this.DBContext = dbContext;

Startup/Program

var dbContext = configuration.GetValue<string>("Configuration:DBContext");
services.AddDbContextFactory<MyDbContext>(options => options.UseSqlServer(dbContext), ServiceLifetime.Singleton);

You component initialization then looks like this.

protected async override void OnInitializedAsyc()
{
  this.employees = await this.Repository.GetEmployeesAsync();
}

Data loading will be dependant on your data server, but the UI will be responsive. You may need to consider paging as the data set grows - you can only display so many rows at once so why fetch them all at once!

  • Related