Я искал удаление строк из базы данных с помощью Blazor. Я пробовал это, но столкнулся с проблемами, требующими длинного кода. Я хочу, чтобы мой проект был простым.
Мой код:
@page "/database"
@attribute [StreamRendering]
@*Form*@
<div class = "row">
<div class = "col-12">
<div class = "card">
<div class = "card-body">
<h1 class = "card-title text-center">DataBase Insert</h1>
<EditForm Model = "employee" OnValidSubmit = "Submit" FormName = "Person">
<DataAnnotationsValidator/>
<label>Name: </label>
<InputText placeholder = "Name" class = "form-control" @bind-Value = "employee!.Name" aria-required = "true" />
<ValidationMessage For = "@(() => employee.Name)" />
<br />
<label>Age: </label>
<InputNumber placeholder = "Age" class = "form-control" @bind-Value = "employee!.Age" aria-required = "true" />
<ValidationMessage For = "@(() => employee.Age)" />
<br />
<label>Address: </label>
<InputText placeholder = "Address" class = "form-control" @bind-Value = "employee!.HomeAddress" aria-required = "true" />
<ValidationMessage For = "@(() => employee.HomeAddress)" />
<br />
<label>WhereFrom: </label>
<InputText placeholder = "WhereFrom?" class = "form-control" @bind-Value = "employee!.WhereFrom" aria-required = "true" />
<ValidationMessage For = "@(() => employee.WhereFrom)" />
<br />
<button type = "submit" class = "btn btn-primary btn-rounded" href = "database">Submit</button>
</EditForm>
</div>
</div>
</div>
</div>
<br />
<br />
@*Database*@
<div class = "row">
<div class = "col-12">
<div class = "card">
<div class = "card-body">
<h1 class = "card-title text-center">DataBase Table</h1>
@*Table*@
<table class = "table table-bordered text-center">
<tr class = "bg-dark text-white">
<td> ID </td>
<td> Name </td>
<td> Age </td>
<td> HomeAddress </td>
<td> WhereFrom </td>
<td></td>
</tr>
@foreach (var employees in Employees)
{
<tr>
<td>@employees.Id</td>
<td>@employees.Name</td>
<td>@employees.Age</td>
<td>@employees.HomeAddress</td>
<td>@employees.WhereFrom</td>
<td><button type = "submit" class = "btn btn-danger" @onclick = "Delete" href = "database">X</button></td>
</tr>
}
</table>
</div>
</div>
</div>
</div>
@inject Data.AppDbContext dbContext
@code {
[SupplyParameterFromForm]
public Employee? employee { get; set; }
public AppDbContext context;
public int SetId { get; set; }
List<Employee> Employees = new List<Employee>();
protected override void OnInitialized()
{
// creates new employee null to fill in and sets the ID
employee ??= new();
// this gets the values from the database for the list
Employees = dbContext._Employee.ToList();
}
protected async void Delete()
{
DeleteFunc(employee!.Id);
await dbContext.SaveChangesAsync();
//update Database
UpdateDatabase();
}
protected async void DeleteFunc(int Id)
{
var employee = await dbContext._Employee.FindAsync(Id);
dbContext._Employee.Remove(employee);
}
private async Task Submit()
{
// this for database
dbContext._Employee.Add(employee);
await dbContext.SaveChangesAsync();
// update database
UpdateDatabase();
}
public void UpdateDatabase()
{
// this refreshes the data in the form
employee = new Employee();
// this is for list to update
Employees.Clear();
Employees = dbContext._Employee.ToList();
StateHasChanged();
}
}
Я пытаюсь сделать это простым и не хочу, чтобы все эти различные сервисы и прочее просто хотели иметь простую кнопку удаления, которая удаляет строку из базы данных. Если это слишком много, я открыт для более длинного кода, но я хочу попытаться избежать этого.
Что я хочу сделать:
protected async void Delete()
{
DeleteFunc(employee!.Id);
await dbContext.SaveChangesAsync();
// update database
UpdateDatabase();
}
protected async void DeleteFunc(int Id)
{
var employee = await dbContext._Employee.FindAsync(Id);
dbContext._Employee.Remove(employee);
}
Я пробую это, но это не работает. Может ли кто-нибудь подсказать, почему?
У вас есть:
protected async void Delete()
{
DeleteFunc(employee!.Id); // not awaited
await dbContext.SaveChangesAsync(); // may happen _during_ the FindAsync
// update database
UpdateDatabase();
}
protected async void DeleteFunc(int Id)
{
var employee = await dbContext._Employee.FindAsync(Id);
dbContext._Employee.Remove(employee);
}
Решение состоит в том, чтобы просто изменить эти два метода на async Task
и дождаться их. Это делает заказ последовательным и разумным.
А затем также используйте
protected override async Task OnInitializedAsync()
{
await UpdateDatabase();
}
async Task UpdateDatabase()
{
// this refreshes the data in the form
employee = new Employee();
// this is for list to update
// Employees.Clear();
Employees = await dbContext._Employee.ToListAsync();
// StateHasChanged();
}
Но учтите, что это не предпочтительный шаблон для использования DbContext с Blazor. Лучше об этом прочитать здесь
Вы можете отредактировать кнопку удаления следующим образом:
<button type = "button" class = "btn btn-danger" @onclick = "() => Delete(emp.Id)">X</button>
Атрибут кнопки @onclick
использует лямбда-выражение () => Delete(employee.Id)
для передачи идентификатора текущей строки в метод Удалить. Метод Удалить теперь принимает параметр id
и находит соответствующего сотрудника, которого нужно удалить.
@code {
[SupplyParameterFromForm]
public Employee? employee { get; set; }
public List<Employee> Employees { get; set; } = new List<Employee>();
protected override async Task OnInitializedAsync()
{
employee ??= new Employee();
UpdateDatabase();
}
private async Task Delete(int id)
{
var emp = await dbContext._Employee.FindAsync(id);
if (emp != null)
{
dbContext._Employee.Remove(emp);
await dbContext.SaveChangesAsync();
UpdateDatabase();
}
}
private async Task Submit()
{
if (employee != null)
{
dbContext._Employee.Add(employee);
await dbContext.SaveChangesAsync();
UpdateDatabase();
}
}
private void UpdateDatabase()
{
Employees = dbContext._Employee.ToList();
StateHasChanged();
}
}
И если вы используете сервер Blazor, не забудьте добавить эту строку: @rendermode InteractiveServer
, чтобы кнопка работала.
Поскольку по умолчанию он находится в статическом режиме (SSR), событие onclick
может не ответить; это удастся только в интерактивном режиме.
см. Создайте полнофункциональное веб-приложение с помощью Blazor:
Содержимое интерактивных страниц предварительно обрабатывается, при этом содержимое сервер изначально генерируется и отправляется клиенту без включение обработчиков событий для отображаемых элементов управления.
Если вы не хотите использовать интерактивный режим, вы также можете сделать это, сделав кнопку методом отправки формы:
<form method = "post" @onsubmit = "() => Delete(emp.Id)" @formname = "@($"DeleteForm_{emp.Id}")">
<AntiforgeryToken />
<button type = "submit" class = "btn btn-danger">X</button>
</form>
это мой результат теста:
@formname = "@($"DeleteForm_{emp.Id}"
что такое DeletForm_, он выдает ошибку
И если все в порядке, можете ли вы помочь мне сделать то же самое с функцией редактирования?
Избегайте
async void
. Вам это не нужно. Кроме того, для эффективного использования[StreamRendering]
используйте OnInitializedAsync и ToListAsync.