How to establish one-to-many relationship for a code-first approach?

babacar diakite 20 Reputation points
2023-02-24T03:48:57.68+00:00

I'm trying to build a recipe app for my spouse. I'm trying to set it up so she can add new recipes to the database as the app grows. When adding new recipe, she will have three drop-down to pick from to construct her new recipe ingredients. First one will contain a list of ingredients that she can choose from, the second one a list of measuring units and the third one a list of quantities. Here is what I got so far. Am I heading in the right direction or am I off? I'm using Entity Framework with a code-first approach: I would like to know how to add the ingredients to the recipe model

>  public class Ingredients
>     {
>         [Key]
>         public int Id { get; set; }
>         public string Name { get; set; }
>         [Required]
>         public int MeasureUnitId { get; set; }
>         [ValidateNever]
>         public MeasureUnit MeasureUnit { get; set; }
>         [Required]
>        
>         public int QuantityUnitId { get; set; }
>         [ValidateNever]
>         public QuantityUnit QuantityUnit { get; set; }
>     }
> ```
> 
> 
> 



> 
> ```
> 
> 
> 

public class IngredientController : Controller { private readonly FoodStoreContext _db; public IngredientController(FoodStoreContext db) { _db = db; } public IActionResult Index() { IEnumerable<Ingredients> ingredientList = _db.ingredients.Include(u => u.MeasureUnit).Include(u => u.QuantityUnit); return View(ingredientList); } [HttpGet] public IActionResult Upsert(int? id) { Ingredients ingredients = new Ingredients(); IEnumerable<SelectListItem> measureUnitList = _db.measureUnit.Select(u => new SelectListItem{ Text = u.Name, Value = u.Id.ToString() }); IEnumerable<SelectListItem> quantityUnitList = _db.quantityUnit.Select(u => new SelectListItem{ Text = u.Name, Value = u.Id.ToString() }); if (id != 0) { ViewBag.measureUnitList = measureUnitList; ViewBag .quantityUnitList = quantityUnitList; return View(ingredients); } else {

        }

        return View(ingredients);
    }
    [HttpPost]
    public IActionResult Upsert(Ingredients obj)
    {
        if (ModelState.IsValid)
        {
            _db.ingredients.Add(obj);
            _db.SaveChanges();
        }
        return RedirectToAction("Index");   
    }
}


SQL Server | Other
SQL Server | Other

Additional SQL Server features and topics not covered by specific categories

Developer technologies | ASP.NET Core | Other

1 answer

Sort by: Most helpful
  1. Muhammad Ahsan Khan 250 Reputation points
    2023-03-27T10:39:37.4366667+00:00

    It seems like you are on the right track with your code-first approach. To establish a one-to-many relationship between your Recipe model and Ingredients model, you can add a navigation property to your Recipe model that references a collection of Ingredients.

    Here is an example:

    public class Recipe
    {
        [Key]
        public int Id { get; set; }
        public string Name { get; set; }
        public virtual ICollection<Ingredient> Ingredients { get; set; }
    }
    public class Ingredient
    {
        [Key]
        public int Id { get; set; }
        public string Name { get; set; }
        public int MeasureUnitId { get; set; }
        public virtual MeasureUnit MeasureUnit { get; set; }
        public int QuantityUnitId { get; set; }
        public virtual QuantityUnit QuantityUnit { get; set; }
        public int RecipeId { get; set; }
        public virtual Recipe Recipe { get; set; }
    }
    public class MeasureUnit
    {
        [Key]
        public int Id { get; set; }
        public string Name { get; set; }
    }
    public class QuantityUnit
    {
        [Key]
        public int Id { get; set; }
        public string Name { get; set; }
    }
    

    Here, the Recipe model has a collection of Ingredients as a navigation property, and the Ingredient model has a Recipe object that references its parent Recipe. You can then use the DbSet.Include method to eagerly load the Ingredients when querying for Recipes.

    var recipes = context.Recipes.Include(r => r.Ingredients);
    

    When creating a new Recipe, you can add new Ingredients to its Ingredients collection and then save the changes to the database.

    var recipe = new Recipe { Name = "Pizza" };
    recipe.Ingredients.Add(new Ingredient { Name = "Flour", MeasureUnitId = 1, QuantityUnitId = 1 });
    recipe.Ingredients.Add(new Ingredient { Name = "Tomato sauce", MeasureUnitId = 2, QuantityUnitId = 2 });
    context.Recipes.Add(recipe);
    context.SaveChanges();
    

    I hope this helps!

    Was this answer helpful?

    0 comments No comments

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.