3

Scenario:

I'm currently creating a basic server side Blazor crud application, Blazor being something I have just started experimenting with.

I've encountered an issue with a back button when navigating back from an edit page to an index page. The issue is as follows:

  1. I edit a record and make some changes to a field without saving
  2. I click the back button which navigates back to the index page
  3. The record that I made changes to within the list of records shows the changes I made in the edit form, however I did not hit save.
  4. I refresh the page and the record returns back to it's original state.

I have tried using a button with an on click and an the following:

<a href="/branches" class="btn btn-sm btn-secondary mr-2"><i class="oi oi-arrow-circle-left"></i> Back</a>

Question:

Any ideas where I'm going wrong?

Index:

@page "/branches"
@inject BranchRepository repository

<GenericList List="branches">    
  <WholeListTemplate>
    <table class="table table-hover">
        <thead>
            <tr>
                <th>Name</th>
                <th>Code</th>
                <th></th>
            </tr>
        </thead>
        <tbody>
            @foreach (var item in branches)
            {
                <tr>
                    <td>@item.sName</td>
                    <td>@item.sBranchNumber</td>
                    <td><a href="/branch/edit/@item.Id" class="btn btn-sm btn-warning">Edit</a></td>
                </tr>
            }
        </tbody>
    </table>
  </WholeListTemplate>
</GenericList>

@code {
  List<Core.Entities.Branch> branches;

  protected async override Task OnInitializedAsync()
  {
    branches = null;
    branches = await repository.GetAllBranches();
  }
}

Edit:

@page "/branch/edit/{id:int}"

@inject NavigationManager navigationManager
@inject BranchRepository repository

<h2>Edit Branch</h2>
<hr />

@if(branch != null)
{
  <BranchEditForm Branch="branch" OnValidSubmit="Update" />
}

@code {
  [Parameter] public int Id { get; set; }

  private Branch branch;

  protected override void OnInitialized()
  {
    branch = repository.GetById(Id);
  }

  private void Update()
  {
    repository.Update(branch);
    navigationManager.NavigateTo("branches");
  }
}

BranchEditForm:

<EditForm Model="Branch" OnValidSubmit="OnValidSubmit">
   <DataAnnotationsValidator />
    <div class="form-row">
      <div class="form-group col-md-6">
         <label>
            Name
         </label>
         <InputText class="form-control" @bind-Value="@Branch.sName" />
         <ValidationMessage For="@(() => Branch.sName)" />
      </div>
       <div class="form-group col-md-6">
         <label>
            Branch Number
         </label>
         <InputText class="form-control" @bind-Value="@Branch.sBranchNumber" />
         <ValidationMessage For="@(() => Branch.sBranchNumber)" />
       </div>
     </div>

    <a href="/branches" class="btn btn-sm btn-secondary mr-2"><i class="oi oi-arrow-circle-left"></i> Back</a>
    <button type="submit" class="btn btn-sm btn-success"><i class="oi oi-document"></i> Save</button>
</EditForm>

@code {
   [Parameter] public Branch Branch { get; set; }
   [Parameter] public EventCallback OnValidSubmit { get; set; }
}
7
  • Does your repo cache objects? I.e. does getbyid return the same object that is shown in the list or are you doing some sort of refetch? I'm wondering if you are editing an instance which is then still displayed on the previous page since blazor is pretty much stateful Commented Mar 4, 2020 at 12:31
  • It does look like my object is cached, my .GetById() method does retrieve the same object in the list. Could it be the way I have set up EF Core and registered my DbContext and repository. The only refetch that is triggered is to get my list for the index with an OnInitilized(). Commented Mar 4, 2020 at 13:01
  • What is the repository lifetime ? Commented Mar 4, 2020 at 13:13
  • @aguafrommars I'm using AddScoped to register my repository so the lifetime is forever. I tried using AddSingleton however, because I'm using DbContext this has not been possible. I have used AddTransient but that made no difference. Commented Mar 4, 2020 at 13:47
  • Have you considered discarding the edits when the edit page is closed if the save button isn't clicked? Wondering if that will help. It does sound like you are editing an instance which is displayed on the previous page. Commented Mar 4, 2020 at 16:18

1 Answer 1

1

Cause

DbContext cached the changes made to the entity

Solution

Through helpful comments, I looked into DbContext caching in EF Core and found a useful post https://codethug.com/2016/02/19/Entity-Framework-Cache-Busting/.

Through this I found out a way to reload an entity or a collection of entities generically:

One Entity

    public async Task ReloadEntity<TEntity>(TEntity entity)
    {
        if (entity != null) await context.Entry(entity).ReloadAsync();

        return;
    }

Multiple Entities

Note - According to the post linked above, this is ideal for a handful of entities. Performance problems may occur if large lists are passed in

    public async Task ReloadEntities<TEntity>(List<TEntity> entities)
    {
        if (entities.Count() > 0)
        {
            foreach (var entity in entities) if (entity != null) await context.Entry(entity).ReloadAsync();
        }

        return;
    }
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.