Blazor中编辑MudBlazor表格记录后自动插入空值行问题求助
问题描述
使用带内联编辑功能的MudBlazor表格组件时,编辑记录会出现异常:原有记录正常更新,但同时会新增一行所有值为0的记录。基于自定义数据库实现了天气预报模板的功能,求问题原因及解决办法。
相关代码
FetchData.razor
<MudTable FixedHeader="true" Height="450px" Elevation="25" Items="GetWeatherForecast()" Filter="new Func<WeatherForecast, bool>(Search)" @bind-customer="forecast" CanCancelEdit="@canCancelEdit" CommitEditTooltip="Commit Edit" OnCommitEditClick="EditWeather" Hover="@hover" Bordered="@bordered" Striped="@striped" HorizontalScrollbar="true" RowEditPreview="BackupItem" RowEditCancel="ResetItemToOriginalValues"> <ToolBarContent> <MudText Typo="Typo.h6">Forecasts</MudText> <br /> <br /> <div></div> <MudSpacer /> </ToolBarContent> <HeaderContent> <MudTh>Tempc</MudTh> <MudTh>Tempf</MudTh> <MudTh>Summary</MudTh> <MudTh>Percentage</MudTh> </HeaderContent> <RowTemplate> @{ float percentage = (float)@context.TemperatureC / sumOfTemperatures * 100; } <MudTd DataLabel="TemperatureC">@context.TemperatureC</MudTd> <MudTd DataLabel="TemperatureF">@context.TemperatureF</MudTd> <MudTd DataLabel="Summary">@context.Summary</MudTd> <MudTd DataLabel="percentage">@percentage</MudTd> </RowTemplate> <RowEditingTemplate> <MudTd DataLabel="TemperatureC"> <MudTextField @bind-Value="@context.TemperatureC" Required /> </MudTd> @{ float percentage = (float)@context.TemperatureC / sumOfTemperatures * 100; } <MudTd DataLabel="TempF">@context.TemperatureF</MudTd> <MudTd DataLabel="Summary">@context.Summary</MudTd> <MudTd DataLabel="percentage">@percentage</MudTd> </RowEditingTemplate> </MudTable> @code{ private string searchString = ""; private bool hover = true; private bool striped = true; private bool bordered = true; private bool ronly = false; private bool canCancelEdit = true; private bool blockSwitch = false; int tempc; private WeatherForecast elementBeforeEdit; bool isOpen; private int sumOfTemperatures; private WeatherForecast forecast = new WeatherForecast(); private List<WeatherForecast> forecasts = new List<WeatherForecast>(); protected override async Task OnInitializedAsync() { GetWeatherForecast(); sumOfTemperatures = forecasts.Sum(f => f.TemperatureC); } private void Save() { weatherService.SaveWeatherForecast(forecast); forecast = new WeatherForecast(); snackBar.Add("Forecast Saved.", Severity.Success); GetWeatherForecast(); OnInitializedAsync(); } private void EditWeather() { weatherService.EditWeatherForecast(forecast); snackBar.Add("Edited", Severity.Success); GetWeatherForecast(); OnInitializedAsync(); } }
WeatherForecastService.cs
public void SaveWeatherForecast(WeatherForecast forecast) { if (forecast.Id == 0) _dbContext.Forecasts.Add(forecast); else _dbContext.Forecasts.Update(forecast); _dbContext.SaveChanges(); } public void EditWeatherForecast(WeatherForecast forecast) { _dbContext.Forecasts.Update(forecast); _dbContext.SaveChanges(); }
问题原因及解决方案
核心原因
- 无效绑定属性:MudTable组件不存在
@bind-customer这个绑定属性,该配置无法正确获取正在编辑的行数据,属于错误配置。 - 全局变量误用:
EditWeather方法没有接收MudBlazor传递的编辑项参数,而是直接使用了全局的forecast变量——这个变量初始化为new WeatherForecast()(Id为0)。EF Core会将Id为0的实体判定为新数据,调用Update时会执行插入操作,导致新增一行全0记录。 - 缺失编辑状态处理:
RowEditPreview和RowEditCancel绑定的方法仅声明未实现,无法正确备份编辑前的数据、回滚取消操作,可能导致数据状态混乱。
修复步骤
- 移除无效绑定:删除MudTable标签中的
@bind-customer="forecast"配置。 - 修改EditWeather方法接收参数:让方法接收OnCommitEditClick传递的编辑项,替换全局变量的使用:
private void EditWeather(WeatherForecast editedForecast) { weatherService.EditWeatherForecast(editedForecast); snackBar.Add("Edited", Severity.Success); GetWeatherForecast(); // 若UI未自动刷新,可手动调用StateHasChanged() } - 实现备份与回滚方法:补充
RowEditPreview和RowEditCancel对应的方法,确保编辑状态正确:private void BackupItem(WeatherForecast item) { // 深拷贝原数据,避免引用类型直接赋值导致原数据被修改 elementBeforeEdit = new WeatherForecast { Id = item.Id, TemperatureC = item.TemperatureC, TemperatureF = item.TemperatureF, Summary = item.Summary // 其他属性按需拷贝 }; } private void ResetItemToOriginalValues(WeatherForecast item) { if (elementBeforeEdit != null) { item.TemperatureC = elementBeforeEdit.TemperatureC; item.TemperatureF = elementBeforeEdit.TemperatureF; item.Summary = elementBeforeEdit.Summary; // 其他属性按需恢复 } } - 优化数据刷新逻辑:
OnInitializedAsync不应在方法内重复调用,GetWeatherForecast更新forecasts列表后,调用StateHasChanged()即可触发UI刷新,无需重新执行初始化逻辑。
内容的提问来源于stack exchange,提问作者gab4bdo
相关产品推荐
相关产品推荐

