noob to blazor and confused about page life cycle and an ever increase number of requests

Viewed 78

I've decided to pick up blazor as recently enjoyed last UWP project and quite like entiry framework to boot.

I've a very basic component, littlally uses a service using an injected IDbContextFactory<>, and EF core.

The app runs fine but I'm noticing an exponential growth in "requests being sent" or at least break-points being hit multiple times on page load.

I'll set a break point in the page / service.cs and the break point is his multiple times. I extend the EF query to include extra collection and that's another 2/3/4 hits on the break point.

I embed a component and that's yet more hits to the break point.

In _Host.cshtml i've set "render-mode" to Server and it's still hitting multiple times.

I'm just curious is this is expected behaviour because of how blazor pre-rendering works along with signalR or if there's an issue with my very basic code.

I've checked with the blazor example app and that hits breakpoints multiple times too.

Service:

public class PostService
    {
        private readonly IDbContextFactory<PostContext> _db;

        public PostService(IDbContextFactory<PostContext> dBContext)
        {
            _db = dBContext;
        }

 public Board GetPost(string? id)
        {
            using (var db = _db.CreateDbContext())
            {
                var posts = db.Posts.FirstOrDefault(p => string.Equals(p.Id,id));
             }
         }
Program.CS:
builder.Services.AddDbContextFactory<PostContext>();

// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddSingleton<PostService>();

Post.razor
@page "/post/{PostId?}"
@inject NavigationManager navMan
@inject PostService postService


@code {
    [Parameter]
    public string? PostId{ get; set; }

    Post? CurrentPost=> postService.GetPost(PostId);
    
}

All very basic I'm just not used to blazor at all lol

2 Answers
 Post? CurrentPost=> postService.GetPost(PostId);

Could become very expensive. You now query everytime you use CurrentPost.

Make CurrentPost a property or a field and load it in OnParametersSet[Async]

You code is mighty expensive on Db access. If I read your code correctly: if CurrentPost has 10 properties you are displaying in the Form, you're going to make 10 database calls and create 10 contexts.

Here's some code snippets based on what you've shown in your question that resolve the issue.

I've:

  1. Made the Db access async.
  2. Loaded the Post ONCE in OnInitializedAsync.

Your service:

public async ValueTask<Post> GetPostAsync(string? id)
        {
            using var db = _db.CreateDbContext();
            var post = await db.Posts.FirstOrDefaultAsync(p => string.Equals(p.Id,id));
            // need to deal with nulls here properly
            return post;
             }
         }
private Post? currentPost;

protected async Task OnInitializedAsync()
{
   currentPost = await PostService.GetPostAsync(postId);
}
Related