Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7576915
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 30, 20262026-05-30T17:02:51+00:00 2026-05-30T17:02:51+00:00

Here’s my situation – I’ve got a DB which has some tables named recipes

  • 0

Here’s my situation – I’ve got a DB which has some tables named recipes, ingredients and recipes_ingredients.

Recipes are composed of 1+ ingredients.

The recipes_ingredients has FKs between the recipes and ingredients table.

The classes that get generated are recipe and ingredient and recipe has a navigation property that looks like so:

public virtual ICollection<ingredients> ingredients { get; set; }

Great, I understand that I get a generated recipe class and a generated ingredient class and that the recipes_ingredients table doesn’t get a class generated since EF views this simply as a navigation property.

Now, I’ve got a function called SetIngredientsForRecipe that looks like so (minus the try-catch code for brevity’s sake:

public void SetIngredientsForRecipe(long recipeId, List<string> ingredients)
{
   using (var db = new FoodEntities(ConnectionString, null, null))
   {
      var existing = GetCurrentIngredients(recipeId);
      var toRemove = existing.Except(ingredients);
      var toAdd = ingredients.Except(existing);
      var recipe = db.recipes.Where(r => r.Id == recipeId).FirstOrDefault();
      foreach (var name in toRemove)
      {
         var entry = recipe.ingredients.Where(i => i.Name == name).FirstOrDefault();
         recipe.ingredients.Remove(entry);
      }
      foreach (var name in toAdd)
      {
         var entry = db.ingredients.Where(i => i.Name == name).FirstOrDefault();
         recipe.ingredients.Add(entry);
      }
      db.SaveChanges();
   }
}

The intent, as the name suggests, is to update the ingredient list for the given recipe to only whatever is in the list. I’m still getting comfortable with EF and wondering if there’s a better (more efficient?) way to accomplish what I’m trying to do.


Follow-up:

Following the suggestions by ntziolis below, I opted to use

recipe.ingredients.Clear() to clear out whatever was in the recipe/ingredient mapping and then use the mocking that was mentioned to quickly add the new ones. Something like this:

foreach (var name in ingredients)
{
  // Mock an ingredient since we just need the FK that is referenced
  // by the mapping table - the other properties don't matter since we're
  // just doing the mapping not inserting anything 

  recipe.ingredients.Add(new Ingredient()
  {
    Name = name
  });
}

and this works very nicely.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-30T17:02:52+00:00Added an answer on May 30, 2026 at 5:02 pm

    General performance guidelines are:

    • try to deal with id’s only
    • mock entities whenever possible, rather than retrieving them from db
    • use the new features of EF4 like Contains in order to simplify and speed up your code

    Based on these principles here is a optimized (not simpler though) solution to your problem:

    public void SetIngredientsForRecipe(long recipeId, List<string> ingredients)
    {
       using (var db = new FoodEntities(ConnectionString, null, null))
       {
          var recipe = db.recipe.Single(r => r.ID == recipeId);
    
          // make an array since EF4 supports the contains keyword for arrays
          var ingrArr = ingredients.ToArray();
    
          // get the ids (and only the ids) of the new ingredients
          var ingrNew = new HasSet<int>(db.ingrediants
            .Where(i => ingrArr.Contains(i.Name))
            .Select(i => I.Id));   
    
          // get the ids (again only the ids) of the current receipe
          var curIngr = new HasSet<int>(db.receipes
            .Where(r => r.Id == recipeId)
            .SelectMany(r => r.ingredients)
            .Select(i => I.Id));        
    
          // use the build in hash set functions to get the ingredients to add / remove            
          var toAdd = ingrNew.ExpectWith(curIngr);
          var toRemove = curIngr.ExpectWith(ingrNew);   
    
          foreach (var id in toAdd)
          {
            // mock the ingredients rather than fetching them, for relations only the id needs to be there
            recipe.ingredients.Add(new Ingredient()
            {
              Id = id
            });
          }
    
          foreach (var id in toRemove)
          {
            // again mock only
            recipe.ingredients.Remove(new Ingredient()
            {
              Id = id
            });
          }
    
          db.SaveChanges();
       }
    }
    

    If you want it simpler you could just clear all ingredients and re add them if necessary, EF might even be clever enough to figure out that the relations haven’t changed, not sure about it though:

    public void SetIngredientsForRecipe(long recipeId, List<string> ingredients)
    {
      using (var db = new FoodEntities(ConnectionString, null, null))
      {    
        var recipe = db.recipe.Single(r => r.ID == recipeId);
    
        // clear all ingredients first
        recipe.ingredients.Clear()
    
        var ingrArr = ingredients.ToArray();
        var ingrIds = new HasSet<int>(db.ingrediants
          .Where(i => ingrArr.Contains(i.Name))
          .Select(i => I.Id)); 
    
        foreach (var id in ingrIds)
        {
          // mock the ingredients rather than fetching them, for relations only the id needs to be there
          recipe.ingredients.Add(new Ingredient()
          {
            Id = id
          });
        }
    
        db.SaveChanges();
      }
    }
    

    UPDATE
    Some coding errors have been corrected.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Here is an example: I have a file 1.js, which has some functions. I
Here is my situation: I have a controller action called OrderFromCategory which fills a
Here is my code, which takes two version identifiers in the form 1, 5,
Here a simple question : What do you think of code which use try
Here is some code I made :) @echo off set source=R:\Contracts\ set destination=R:\Contracts\Sites\ ROBOCOPY
Here is the situation, I am attempting to fire a set of Gallio tests
here is the scenario 1: user starts to type some word, autocomplete engine shows
Here is my situation: I am using telerik with winform. I have a dataset
Here is a section of code which is giving me a different answer to
Here's a basic regex technique that I've never managed to remember. Let's say I'm

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.