使用已删除项目的列表更新数据库的最佳方法

发布于 2025-01-17 00:37:16 字数 1885 浏览 3 评论 0原文

我正在使用 Asp.NET 6.0 和 Razor 页面开发一个菜谱 Web 应用程序。有三个数据库表:配方、成分和食物。

每个食谱都有名称、准备工作和成分列表。我喜欢在每个菜谱的一页上完成大部分 CRUD 操作。创建页面工作正常,现在我想扩展该功能以编辑同一页面上的数据。在这里您可以看到创建/编辑页面

如果提供了 ID,则 OnGetAsync 会加载配方和配料:

       public async Task<IActionResult> OnGetAsync(int? id)
        {
            if (id != null)
            {
                Recipe = await _context.Recipes.Where(i => i.ID == id).FirstAsync();
                IngredientList = await _context.Ingredients
                    .Include(r => r.Food1)
                    .Where(i => i.RecipeID == id)
                    .ToListAsync();
            }
            return Page();
        }

然后还有向配料列表添加或删除配料的函数。在调用 SaveRecipeAsync(按钮创建)之前,不会对数据库进行任何更改。

public async Task<IActionResult> OnPostSaveRecipeAsync(int? id)
        {
            var oneRecipe = new Recipe();
            // Error für ModelState Food.Name abfangen.
            ClearFieldErrors(key => key.Contains("Food.Name"));
            if (!ModelState.IsValid)
            {
                return Page();
            }
            oneRecipe.ID = Recipe.ID;
            oneRecipe.Name = Recipe.Name;
            oneRecipe.Preperation = Recipe.Preperation;
            oneRecipe.Ingredients = IngredientList;
            _context.Recipes.Update(oneRecipe);          

            await _context.SaveChangesAsync();
            return RedirectToPage("./Index");
        }

问题:

  • 我正在努力解决如何保存成分表中更改的数据。从成分列表中删除的项目不会在数据库中删除。添加和编辑条目正在工作。

我尝试的解决方案:

  • 在IngredientList中删除Ingredient时,直接在上下文/数据库中删除该Ingredient。将违背立即保存所有内容的方法,我需要查明它是否已经在数据库中或仅在成分列表中。
  • 删除所有与recipeID相关的相应成分,并重新创建其他成分。听起来不太聪明。 问候,卡多

I'm working on a recipe Webapp with Asp.NET 6.0 and Razor pages. There are three database tables : recipe, ingredient and food.

Each Recipe has a Name, Preperation and list of Ingredients. I like to do most of the CRUD operation on one page for each recipe. The Create page is working fine and now I want to extend the function to also edit the data on the same page. Here you can see the Create/Edit Page.

OnGetAsync loads Recipe and Ingredients if an ID is provided:

       public async Task<IActionResult> OnGetAsync(int? id)
        {
            if (id != null)
            {
                Recipe = await _context.Recipes.Where(i => i.ID == id).FirstAsync();
                IngredientList = await _context.Ingredients
                    .Include(r => r.Food1)
                    .Where(i => i.RecipeID == id)
                    .ToListAsync();
            }
            return Page();
        }

And then there are functions to add or delete Ingredients to the IngredientList. No changes are made to the database until SaveRecipeAsync (Button Create) is called.

public async Task<IActionResult> OnPostSaveRecipeAsync(int? id)
        {
            var oneRecipe = new Recipe();
            // Error für ModelState Food.Name abfangen.
            ClearFieldErrors(key => key.Contains("Food.Name"));
            if (!ModelState.IsValid)
            {
                return Page();
            }
            oneRecipe.ID = Recipe.ID;
            oneRecipe.Name = Recipe.Name;
            oneRecipe.Preperation = Recipe.Preperation;
            oneRecipe.Ingredients = IngredientList;
            _context.Recipes.Update(oneRecipe);          

            await _context.SaveChangesAsync();
            return RedirectToPage("./Index");
        }

Problem:

  • I'm struggling with how to save the changed data from the ingredients table. The Items removed from the IngredientList are not removed in the database. Adding and editing of entries is working.

Solutions I tried:

  • Delete the Ingredient directly in the context / database when deleting it in the IngredientList. Will go against the appraoch to save all at once and I need to find out if it is already in the database or only in the IngredientList.
  • Delete all corresponding Ingredients connected to the recipeID and create the others again. Sounds not that smart.
    Regards, Cado

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

爱的故事 2025-01-24 00:37:16

我只是采用了将所有“已删除成分”写入另一个隐藏列表的解决方案:

[BindProperty]
public List<Ingredient> DeletedIngredientList { get; set; } = new List<Ingredient>();

public  IActionResult OnPostRemoveIngredientAsync(int id)
{            
    var delIngredient = IngredientList[id];
    if (delIngredient.RecipeID == 0) //not good for the first ingredient...
    {
        DeletedIngredientList.Add(IngredientList[id]);
    }
    //Remove from list for view effect            
    IngredientList.Remove(IngredientList[id]);            

    ModelState.Clear();
    return Page();
}

public async Task<IActionResult> OnPostSaveRecipeAsync(int? id)
{         
[...] 
    // Delete ingredients 
    foreach (Ingredient i in DeletedIngredientList)
    {                
        Ingredient delIng = _context.Ingredients.Where(ing => ing.ID == i.ID).FirstOrDefault();
        if(delIng != null)
            _context.Ingredients.Remove(delIng);   
        
    }
    await _context.SaveChangesAsync();
[...]
}

我必须在视图上使用此DeletedIngredientList,并且之后只有使用的值可用。就我而言,ID:

@for (int i = 0; i < @Model.DeletedIngredientList.Count; i++)
{ 
    <input type="hidden" asp-for="@Model.DeletedIngredientList[i].ID" />
}

让我知道是否有更优雅的解决方案可用:)

I just went with the solution to write all "deleted Ingredients" to another hidden list:

[BindProperty]
public List<Ingredient> DeletedIngredientList { get; set; } = new List<Ingredient>();

public  IActionResult OnPostRemoveIngredientAsync(int id)
{            
    var delIngredient = IngredientList[id];
    if (delIngredient.RecipeID == 0) //not good for the first ingredient...
    {
        DeletedIngredientList.Add(IngredientList[id]);
    }
    //Remove from list for view effect            
    IngredientList.Remove(IngredientList[id]);            

    ModelState.Clear();
    return Page();
}

public async Task<IActionResult> OnPostSaveRecipeAsync(int? id)
{         
[...] 
    // Delete ingredients 
    foreach (Ingredient i in DeletedIngredientList)
    {                
        Ingredient delIng = _context.Ingredients.Where(ing => ing.ID == i.ID).FirstOrDefault();
        if(delIng != null)
            _context.Ingredients.Remove(delIng);   
        
    }
    await _context.SaveChangesAsync();
[...]
}

I had to use this DeletedIngredientList on the view, and only the value which is used is available afterwards. In my case the ID:

@for (int i = 0; i < @Model.DeletedIngredientList.Count; i++)
{ 
    <input type="hidden" asp-for="@Model.DeletedIngredientList[i].ID" />
}

Let me know if there is a more elegant solution available :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文