Удаление Entity Framework по идентификатору (SQL и простой способ)

Я искал удаление строк из базы данных с помощью 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);
}

Я пробую это, но это не работает. Может ли кто-нибудь подсказать, почему?

Избегайте async void. Вам это не нужно. Кроме того, для эффективного использования [StreamRendering] используйте OnInitializedAsync и ToListAsync.

Henk Holterman 21.08.2024 06:29
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
0
1
50
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

У вас есть:

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>

это мой результат теста:

gdl.space/sapokoweve.cs <- обновленный код, я получаю @formname = "@($"DeleteForm_{emp.Id}" что такое DeletForm_, он выдает ошибку
Gweam 21.08.2024 13:43

И если все в порядке, можете ли вы помочь мне сделать то же самое с функцией редактирования?

Gweam 21.08.2024 18:02

Другие вопросы по теме